头歌操作系统实训线程基础知识

第1关:线程操作实战1

本关任务:编写一个小程序取消已生成线程,然后输出入栈信息。

相关知识

为了完成本关任务,你需要掌握:线程栈的相关知识。

线程的退出等待

线程退出等待 1)pthread_exit(void* _retval) 库函数调用可以结束一个线程,结束方式和进程exit()类似。

2)等待线程 为了有效同步子线程,主线程中豆浆等待子线程结束,显示等待某线程结束可以调用pthread_join()函数,类似于进程的wait(),声明如下:

 
  1. int pthread_join(pthread_t _th, void **_pthread_return)
  2. _th 为被等待线程的ID(设置某个线程为独立线程,则可以调用pthread_detach(pthread_t __th))
  3. _pthread_return 为一个用户定义的指针,指向一个保存等待线程的完整退出状态的静态区域,用来存储被等待线程的返回值

阻塞调用当前线程的线程,直到此线程退出。当函数返回,处于被等待状态的线程资源被收回。

编程要求

根据提示,在右侧编辑器编写代码,增强对pthread_cleanup_push,pthread_cleanup_pop等函数的使用。

测试说明

平台会对你编写的代码进行测试:

代码编译 预期输出:

test_cancel

test message

test message

test message cleanup

#include<pthread.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>

void cleanup()
{
	printf("cleanup\n");
}
void *test_cancel(void)
{
	/*补充代码1,使用pthread_cleanup_push/pop,进行退出前操作*/
    pthread_cleanup_push(cleanup,NULL);

	printf("test_cancel\n");
	while(1)
	{
		printf("test message\n");
		sleep(1);
	}
	/*补充代码2,使用pthread_cleanup_push/pop,进行退出前操作*/
	pthread_cleanup_pop(1);
}
int main()
{
	pthread_t tid;
	pthread_create(&tid,NULL,(void *)test_cancel,NULL);
	sleep(2);
	pthread_cancel(tid);
	pthread_join(tid,NULL);
}

第2关:线程操作实战2

任务描述

本关任务:编写一个小程序实现不同状态下的取消线程设置。

相关知识

为了完成本关任务,你需要掌握:取消线程的相关操作。

取消线程

(1)发起取消 即取消正在执行线程的操作,需要满足条件。 pthread_cancel()取消线程,调用的是取消线程清理处理程序(pthread_cleanup_push) 1)线程是否可以被取消,默认可以取消。 2)线程处于可取消点才能取消,发起取消不一定能立即取消,到取消点才可以。 (2)设置可取消状态 pthread_setcancelstate()和pthread_setcanceltype()用来设置和查询当前线程的可取消性状态或类型。

 
  1. pthread_setcancelstate(int _state,int *_oldstate)
  2. state为要设置的新状态值;
  3. oldstate存储原来状态。
  4. 1)PTHREAD_CANCEL_DISABLE 针对目标线程的取消请求将处于未决状态(未处理但存在)除非线程修改自己状态,否则不会被取消。
  5. 2)PTHREAD_CANCEL_ENABLE,针对目标线程的取消请求将被传递,创建线程时是默认状态

(3)设置取消类型 pthread_setcanceltype()设置取消类型,在允许被取消的线程在接收到取消操作后是立即终止还是等到取消点终止。

 
  1. int pthread_setcanceltype(int _type, int *_oldtype)
  2. type调用线程新的可取消性;
  3. oldtype存储原来的类型。
  4. PTHREAD_CANCEL_ASYNCHRONOUS,可随时执行新的或未决的取消请求。
  5. PTHREAD_CANCEL_DEFERRED,目标达到取消点前处于未决状态(请求已发出但未处理)

在创建线程时,可取消类型设置PTHREAD_CANCEL_DEFERRED,如果禁用线程的可取消性状态,则可取消性类型设置不会立即生效,取消请求都保留为未决状态。但一旦重新启用可取消性,新类型将会生效。 成功完成pthread_setcancelstate和pthread_setcanceltype将返回0,失败返回错误编号,不许设置error变量。

编程要求

根据提示,在右侧编辑器补充代码,代码思路是先开一个线程a_thread,调用thread_function函数,线程函数中先休眠1秒,然后输出一段提示,主函数休眠10秒,a_thread线程开始跑。function函数中,先将线程的可取消状态设置成DISABLE,当前无法取消线程,等待3秒输出当前线程无法取消,然后循环输出三次,每秒一次。将取消状态设置成ENABLE,可取消,线程休眠200秒,返回主程序,输出取消线程,主程序将线程取消pthread_cancel ,输出等待线程完成,pthread_join等待子线程结束,释放所有缓存。请补充代码,分别将取消状态设置为DISABLE和ENABLE。

测试说明

平台会对你编写的代码进行测试:

代码编译 预期输出: Cancelling thread... thread cancle type is disable,can't cancle this thread Thread is running (0)... Thread is running (1)... Thread is running (2)... Now change ths canclestate is ENABLE Waiting for thread to finish...

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>

void *thread_function(void *arg);

int main(int argc,char *argv[]) 
{
    int res;
    pthread_t a_thread;
    void *thread_result;

    res = pthread_create(&a_thread, NULL, thread_function, NULL);//创建线程
    if (res != 0) 
	{
        perror("Thread creation failed");
        exit(EXIT_FAILURE);
    }
    printf("Cancelling thread...\n");
    sleep(10);	
    res = pthread_cancel(a_thread);//取消子线程
    if (res != 0) 
	{
        perror("Thread cancelation failed");
        exit(EXIT_FAILURE);
    }
    printf("Waiting for thread to finish...\n");
    sleep(10);	
    res = pthread_join(a_thread, &thread_result);//等待子线程结束
    if (res != 0) 
	{
        perror("Thread join failed");
        exit(EXIT_FAILURE);
    }
    exit(EXIT_SUCCESS);
}

void *thread_function(void *arg) //新线程执行函数
{
    int i, res, j;
    sleep(1);
    /*请编写代码,将线程的取消状态设置为DISABLE*/
    res =pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,NULL);
    if (res != 0) 
	{
        perror("Thread pthread_setcancelstate failed");
        exit(EXIT_FAILURE);
    }
	sleep(3);
    printf("thread cancle type is disable,can't cancle this thread\n");//打印不可取消状态信息
    for(i = 0; i <3; i++) 
	{
        printf("Thread is running (%d)...\n", i);
        sleep(1);
    }

    /*请编写代码,将取消状态设置为ENABLE*/
    res = res =pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);

    if (res != 0) 
	{
        perror("Thread pthread_setcancelstate failed");
        exit(EXIT_FAILURE);
    }
	else
		printf("Now change ths canclestate is ENABLE\n");
	sleep(7);//休眠7秒 
   pthread_exit(0);
}

第3关:线程操作实战3

任务描述

本关任务:编写一个小程序修改线程的私有变量查看对全局变量的影响。

相关知识

为了完成本关任务,你需要掌握并理解:线程的全局数据与私有数据。

线程全局变量与私有变量

经常用全局变量以实现多个函数共享数据,由于数据空间共享,全局变量共有,有的需要提供线程私有的全局变量,例如每个线程维护一个链表,使用相同函数操作,使用同名而不同内存地址的线程私有数据结构,这样的数据结构可以由POSIX线程库维护,称为线程私有数据TSD (1)创建、注销线程私有数据 ①创建TSD pthread_key_create(pthread_ket_t *key,2) 从TSD池中分配一项,将其地址值赋给key,第二个参数不为空,在线程退出(pthread_exit())时以key所关联的数据为参数调用其指向的资源释放函数,以释放分配的缓冲区。 不论哪个线程调用pthread_key_create(),创建的key所有线程都可以访问,每个线程根据需要往key填入不同的值,提供了一个同名不同值的全局变量。

②注销TSD int pthread_key_delete(pthread_key_t key) 这个函数不检查当前是否有线程正在使用TSD,也不会调用清理函数,只是将TSD释放供下一次调用pthread_key_create 使用。

(2)读写线程私有数据 TSD的读写通过专门的POSIX Thread函数进行

 
  1. int pthread_setspecific(pthread_key_t key,const coid *pointer)
  2. void *pthread_getspecific(pthread_key_t key)

函数pthread_setspcific()将pointer的值(不是所指内容)与key相关联,pthread_getspecific()函数将与key相关联的数据读出。

,

,

先设置一个全局变量k=100,在主函数中先创建两个线程,线程1和2都输出线程赋值的字符串helloworld,线程2休眠1秒让线程1先跑,线程1将全局变量key改成10,输出key值和当前线程号,线程1跑完返回主线程pthread_join等待结束,线程2休眠完开跑,输出key,因为key值是全局变量,当前key已经被线程1修改,然后返回结束。

编程要求

根据提示,在右侧编辑器补充代码,代码思路是先创建两个线程child1、child2,两个线程同时开跑,线程1和2都输出当前欲修改的值以及自身的线程标识,然后分别用setspecific修改key值,为10和20,分别等待1秒和2秒,并打印当前的全局变量值,线程2先打印,线程1后打印,线程1和2分别都对私有的全局变量进行改变,但互不影响。请补充代码,分别将线程1的私有全局变量值修改成10,线程2 的私有全局变量值修改成20。

测试说明

平台会对你编写的代码进行测试:

代码编译 预期输出:

set key value 10 in thread 1 thread one sleep 2 until thread two finish

set key value 20 in thread 2

thread 2 returns 20 destructor excuted

thread 1 returns 10 destructor excuted

#include <stdio.h> 
#include <pthread.h> 
 
pthread_key_t key; //线程私有数据类型
void echomsg(void *t) 
{ 
	printf("destructor excuted\n"); //线程退出时执行
} 
 
void * child1(void *arg) 
{ 
	int i=10;
	int tid=pthread_self(); 
	printf("\nset key value %d in thread 1\n",i); 
	/*将线程1的私有key值修改为10*/
    pthread_setspecific(key, (void*)&i);
 
 
	printf("thread one sleep 2 until thread two finish\n");
	sleep(3); //等待线程2修改key值
	printf("\nthread 1 returns %d\n",*((int *)pthread_getspecific(key))); //打印当前线程信息
} 
 
void * child2(void *arg) 
{ 
	int temp=20;
	int tid=pthread_self(); 
	sleep(1); 
	printf("\nset key value %d in thread 2\n\n",temp); 
	/*将线程2的私有key值修改为20*/
    pthread_setspecific(key, (void*)&temp);
 
 
	sleep(1); 
	printf("thread 2 returns %d\n",*((int *)pthread_getspecific(key))); //打印当前线程信息
} 
 
int main(void) 
{ 
	pthread_t tid1,tid2; 
	pthread_key_create(&key,echomsg); 
	pthread_create(&tid1,NULL,(void *)child1,NULL); //创建线程1
	pthread_create(&tid2,NULL,(void *)child2,NULL); //创建线程2
	pthread_join(tid1,NULL);//等待线程1结束
	pthread_join(tid2,NULL);//等待线程2结束
	pthread_key_delete(key); //释放全局变量
	return 0; 
}

  • 24
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
三、实验内容与要求 1、熟悉windows的编程接口,使用系统调用编程实现将参数1对应文件1.txt和参数2对应文件2.txt的内容合并到参数3对应文件zong.txt中(上传文件名为学号后5位ex0701.c)。 2、使用windows提供的命令将文件1.txt和文件2.txt的内容合并到文件total.txt中 (请将实现的操作命令写入下题批处理文件的第一行)。 3、主管助理小张经常接收公司员工发来的文件,开始为了节省时间,小张将下载的文件都保存在文件夹xiazai中(文件名如图1所示,下载后直接解压即可),这样不便于后期的统计和分类管理,现在领导要求必须为所有员工(90人)每人单独建立一个文件夹(以员工工号命名10201、10202......10290),然后将他们提交的文件分别剪切到各自对应的文件夹中(如图2所示)。于是小张开始为7名员工建立文件夹,再一个一个的去做……同学们想想有没有一种方法能快速完成所要求的操作呢? 请熟悉windows的命令接口,使用windows提供的常用命令copy、md、del等编写一个批处理文件(上传文件名为学号后5位ex0703.bat),实现所要求的功能: 1、启动linux系统或通过windows telnet到linux。 2、用huas用户名和密码123456登入系统中。 3、打开一终端窗口(在linux桌面上单击右键,选择从终端打开)。然后在其中输入以下命令实验。 4、熟悉常用操作命令. 5、编辑如下源代码(实验教材P86 1.进程的创建)并保存 二、实验目的 (1)加深对进程概念的理解,明确进程和程序的区别。 (2)分析进程竞争资源现象,学习解决进程互斥的方法。 (3了解Linux系统中进程通信的基本原理。 三、实验内容与要求 (1)任务一:编写一段程序,使其实现进程的软中断通信。 要求:使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即按DEL键);当捕捉到中断信号后,父进程用系统调用Kill()向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止: Child Processll is Killed by Parent! Child Processl2 is Killed by Parent! 父进程等待两个子进程终止后,输出如下的信息后终止 Parent Process is Killed! (2)任务二:在上面的程序中增加语句signal (SIGNAL, SIG-IGN)和signal (SIGQUIT, SIG-IGN),观察执行结果,并分析原因。 (3)任务三:进程的管道通信 编制一段程序,实现进程的管道通信。 使用系统调用pipe()建立一条管道线;两个子进程P1和P2分别向管道中写一句话: Child 1 is sending a message! Child 2 is sending a message! 而父进程则从管道中读出来自于两个子进程的信息,显示在屏幕上。 要求父进程先接收子进程P1发来的消息,然后再接收子进程P2发来的消息。 二、实验目的 自行编制模拟程序,通过形象化的状态显示,加深理解进程的概念、进程之间的状态转换及其所带来的PCB内容 、组织的变化,理解进程与其PCB间的一一对应关系。 三、实验内容与要求 1)设计并实现一个模拟进程状态转换及其相应PCB内容、组织结构变化的程序。 2)独立编写、调试程序。进程的数目、进程的状态模型(三状态、五状态、七状态或其它)以及PCB的组织形式可自行选择。 3)合理设计与进程PCB相对应的数据结构。PCB的内容要涵盖进程的基本信息、控制信息、资源需求及现场信息。 4)设计出可视性较好的界面,应能反映出进程状态的变化引起的对应PCB内容、组织结构的变化。 二、实验目的 存储管理的主要功能之一是合理地分配空间。请求页式管理是一种常用的虚拟存储管理技术。本实验的目的是通过请求页式管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法。 三、实验内容与要求 通过计算不同算法的命中率比较算法的优劣。同时也考虑了用户内存容量对命中率的影响。页面失效次数为每次访问相应指令时,该指令所对应的页不在内存中的次数。 计算并输出下属算法在不同内存容量下的命中率。  先进先出的算法(FIFO); 最近最少使用算法(LRU) 二、实验目的 死锁会引起计算机工作僵死,因此操作系统中必须防止。本实验的目的在于使用高级语言编写和调试一个系统动态分配资源的简单模拟程序,了解死锁产生的条件和原因,并采用银行家算法有效地防止死锁的发生,以加深对课堂上所讲授的知识的理解。 三、实验内容与要求 设计有n个进程共享m个系统资源的系统,进程可动态的申请和释放资源,系统按各进程的申请动态的分配资源。 系统能显示各个进程申请和释放资源,以及系统动态分配资源的过程,便于用户观察和分析。 四、算法描述(含数据结构定义)或流程图 (一) 数据结构 1. 可利用资源向量Available ,它是一个含有m个元素的数组,其中的每一个元素代表一类可利用的资源的数目,其初始值是系统中所配置的该类全部可用资源数目。其数值随该类资源的分配和回收而动态地改变。如果Available(j)=k,标是系统中现有Rj类资源k个。 2. 最大需求矩阵Max,这是一个n×m的矩阵,它定义了系统中n个进程中的每一个进程对m类资源的最大需求。如果Max(i,j)=k,表示进程i需要Rj类资源的最大数目为k。 3. 分配矩阵Allocation,这是一个n×m的矩阵,它定义了系统中的每类资源当前一分配到每一个进程的资源数。如果Allocation(i,j)=k,表示进程i当前已经分到Rj类资源的数目为k。Allocation i表示进程i的分配向量,有矩阵Allocation的第i行构成。 4. 需求矩阵Need,这是一个n×m的矩阵,用以表示每个进程还需要的各类资源的数目。如果Need(i,j)=k,表示进程i还需要Rj类资源k个,才能完成其任务。Need i表示进程i的需求向量,由矩阵Need的第i行构成。 上述三个矩阵间存在关系:Need(i,j)=Max(i,j)-Allocation(i,j)。 (二) 银行家算法 Request i 是进程Pi 的请求向量。Request i (j)=k表示进程Pi请求分配Rj类资源k个。当Pi发出资源请求后,系统按下述步骤进行检查: 1. 如果Request i ≤Need,则转向步骤2;否则,认为出错,因为它所请求的资源数已超过它当前的最大需求量。 2. 如果Request i ≤Available,则转向步骤3;否则,表示系统中尚无足够的资源满足Pi的申请,Pi必须等待。 3. 系统试探性地把资源分配给进程Pi,并修改下面数据结构中的数值: 二、实验目的 磁盘是高速、大容量、旋转型、可直接存取的存储设备。它作为计算机系统的辅助存储器,担负着繁重的输入输出工作,在现代计算机系统中往往同时会有若干个要求访问磁盘的输入输出要求。系统可采用一种策略,尽可能按最佳次序执行访问磁盘的请求。由于磁盘访问时间主要受寻道时间T的影响,为此需要采用合适的寻道算法,以降低寻道时间。本实验要求模拟设计一个磁盘调度程序,观察调度程序的动态运行过程。通过实验来理解和掌握磁盘调度的职能。 三、实验内容与要求 分别模拟如下磁盘调度算法,对磁盘进行移臂操作:  先来先服务算法  最短寻道优先算法 1. 假设磁盘只有一个盘面,并且磁盘是可移动头磁盘。 2. 磁盘是可供多个进程共享的存储设备,但一个磁盘每个时刻只能为一个进程服务。当有进程在访问某个磁盘时,其它想访问该磁盘的进程必须等待,直到磁盘一次工作结束。当有多个进程提出输入输出请求而处于等待状态时,可用磁盘调度算法从若干个等待访问者中选择一个进程,让它访问磁盘。为此设置“驱动调度”进程。 3. 由于磁盘与处理器是并行工作的,所以当磁盘在为一个进程服务时,占有处理器的其它进程可以提出使用磁盘(这里我们只要求访问磁道),即动态申请访问磁道,为此设置“接受请求”进程。 4. 为了模拟以上两个进程的执行,可以考虑使用随机数来确定二者的允许顺序,参考程序流程图。 5. “接受请求”进程建立一张“进程请求I/O”表,指出等待访问磁盘的进程要求访问的磁道,表的格式如下: 进程名 要求访问的磁道号 6. 磁盘调度的功能是查“请求I/O”表,当有等待访问的进程时,按磁盘调度算法从中选择一个等待访问的进程,按其指定的要求访问磁道。流程图中的“初始化”工作包括:初始化“请求I/O”表,设置当前移臂方向;当前磁道号。并且假设程序运行前“请求I/O”表中已有若干进程(4~8个)申请访问相应磁道。
TIPTOP软件   台湾鼎新公司的一款ERP产品,与神州数码的易拓是同宗产品。 编辑本段深圳利谱(Tiptop)    公司标志 深圳市利谱信息技术有限公司成立于2000年7月,是深圳市高新技术企业,专门从事信息安全技术及产品的开发研制与相关服务。公司坚持"高科技创新、高水平管理、高标准服务"的经营理念,致力于提高我国政府机关、军警、企事业单位及个人的计算机信息安全防范水平,减少国家秘密、商业秘密和个人隐私的泄漏可能,开发、生产和推广信息安全产品,提供用户培训、现场评估、用户定制等技术服务,为用户计算机的网络安全提供整体解决方案。 编辑本段德国蒂普拓普(TIP TOP)公司   德国蒂普拓普(TIP TOP)公司创立于1923年,其全称为施塔格鲁伯奥托格鲁伯公司。总部位于 德国慕尼黑,它是全球最大的冷硫化橡胶修补材料、防磨损及防腐蚀的橡胶材料的制造商之一。   在工业硫化领域,TIP TOP公司生产并销售各类特种橡胶和模制产品,用于防磨损、防腐蚀和防噪音的工业应用,公司生产的冷硫化补片、补条、T2修补系列及粘接剂等产品,代表着世界最高技术水平,从而被众多的矿山、码头、电厂、水泥厂所采用。   在轮胎服务领域,TIP TOP生产且经营一体化的补胎材料、工具及设备。在过去的几十年中,TIP TOP一直代表着轮胎修补的最高质量水准,无时不在世界的每个角落证明着它的不凡,从单车胎,摩托车胎及小车胎到世界上目前最大的工程胎;从橡胶内胎,斜胶胎到子午线胎,都能用TIP TOP的材料和设备进行修补;其优异的品质和层出不穷的新产品使其在全球同行业中始终保持着领先的地位。1994-1995年,TIP TOP在同行业中成为全球第一家通过ISO 9001和ISO 9002质量认证的公司。   蒂普拓普公司在全球拥有四千五百多名雇员,八家生产(加工)厂以及十三家分布于美国、澳洲、日本、英国、法国、奥地利、芬兰、荷兰、西班牙、丹麦、南非及中国的全资子公司。另外公司还拥有一个遍布全球的一百四十多个国家的销售和服务商网络,经营的产品多达十四万种,其年营业额超过六亿欧元。 编辑本段深圳天凌高(Tiptop)实业发展有限公司   TIPTOP是国内最早生产肘节夹具和焊接组合夹具的公司,从事工装行业夹具多年,具有丰富的行业经验,深悉工装夹具对于行业产品质量、成本之间的重要性。经过多年的积累,开发了几十个系列工装夹具标准产品,为业界设计和制造工装夹具时提供选择标准件和模组产品。提高工装夹具制造效率。 TIPTOP工装夹具   TIPTOP与德国、日本、美国等世界发达国家公司进行技术合作,成立了自己的夹具标准研究中心,多项产品获得专利并成功应用到产业中。TIPTOP公司技术中心汇聚了一大批理论基础扎实、技术精湛、实践经验丰富、极具创造力的工程技术人员,可以为客户在较短的时间内提供合理先进的设计方案,使我们的客户在较短的时间内花最少的人力、物力、财力取得最好的收益。   TIPTOP产品主要为工装夹具行业提供标准件,引领行业标准化。同时为客户提供多种产品选择,并为行业提供解决方案。   TIPTOP提供焊接组合夹具系统,机床柔性夹具系统,肘节夹具系列,气,油压转角缸夹具,管道焊接夹具器材,汽车焊接夹具标准件,检测组合夹具,夹钳,铝组合结构件.上万种型号的商品。多种规格产品取得了国家专利权和被评为高新技术产品。   TIPTOP产品广泛运用于机箱机柜、车体制造、工程机械、钣金加工、设备装配、检测平台、医疗器械、机器人技术、航天器制造等制造领域。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值