您好,欢迎访问三七文档
当前位置:首页 > 临时分类 > UNIX操作系统实验6
UNIX操作系统实验首都师范大学信息工程学院系统分析与管理实验室12目录1、UNIX安装及基本操作………………………………………2、UNIX编程基础……………………………………….3、UNIX进程实验……………………………………….4、UNIX进程间通信……………………………………..5、UNIX文件系统实验………………………………………..6、UNIX综合实验………………………………………..19223346491实验六综合实验(多线程与死锁)一、背景知识操作系统中的一个进程在同一时刻只能做一件事情,有了多个控制线程之后,在程序设计时可以把进程设计成在同一时刻能够做不止一件事,每个线程处理各自独立的任务,而且多个线程之间可以实现数据的共享,这种方法有很多好处。但是共享数据必须保持一致性,因此我们通过对互斥量加锁,确保同一时间只有一个线程操作共享数据。这个势必带来一个问题,对互斥量操作不当的话,就会引起死锁。研究死锁的情况,可以让我们在以后的程序中更好地避免死锁问题。在Linux环境中,我们通过有目的地设计死锁程序,观察多线程死锁的情况,分析多线程对互斥量操作的要点,从而在以后的程序中尽可能地避免死锁的发生。二、实验内容1、单线程与多线程对互斥量操作如果线程对同一个互斥量加锁两次,那么这个线程自身就会陷入死锁状态。在Linux环境下,通过设计两个实验来分析这种情况。单线程程序,main线程对互斥量进行两次加锁,查看程序运行情况。图1两次加锁情况参考程序:------------------------------------------------------------------------------------------------thread1.c--------------#includestdlib.h#includestdio.h#includepthread.h#includeunistd.hstructfoo{//定义structfoointf_count;pthread_mutex_tf_lock;};structfoo*fp;//定义全局变量fpstructfoo*//结构体fp初始化foo_alloc(void){2structfoo*fp;if((fp=(foo*)malloc(sizeof(structfoo)))!=NULL){//初始化fpfp-f_count=0;if(pthread_mutex_init(&fp-f_lock,NULL)!=0){//初始化互斥锁free(fp);return(NULL);}}return(fp);}intmain(void){//main线程fp=foo_alloc();printf(initfp,fp-f_count:%d\n,fp-f_count);/***firstlock****/printf(firstlock:);if(pthread_mutex_lock(&fp-f_lock)==0){//第一次对互斥量fp-f_lock加锁printf(locksuccess!\n);//加锁成功,返回值为0,其它任何情况都表示加锁不成功fp-f_count++;//对结构体fp中的值进行修改fp-f_count++;printf(firstlock,fp-f_count:%d\n,fp-f_count);}elseprintf(lockwrong!\n);//pthread_mutex_unlock(&fp-f_lock);//解除第一次的锁(选择打开)/***lockagain****/printf(secondlock:);//第二次对互斥量进行加锁if(pthread_mutex_lock(&fp-f_lock)==0){printf(lockagainsuccess!\n);fp-f_count++;fp-f_count++;printf(secondlock,fp-f_count:%d\n,fp-f_count);}elseprintf(lockagainwrong!\n);//在main线程中只对互斥量进行加锁,未解锁pthread_mutex_destroy(&fp-f_lock);//销毁互斥锁,并释放fpfree(fp);printf(mainthreadexit!\n);//输出main线程退出提示exit(0);//main线程退出}------------------------------------------------------------------------------------------------thread1.c--------------在Linux下用g++(即C++的编译器)进行编译链接,并调试运行,结果如下:请记录结果:3实验分析(在结果中分析线程可能的状态,必要时修改程序,加入暂停,以便观察):对多线程而言,main线程和新创建thread1,main线程对互斥量进行两次加锁,而thread1只输出两句话,不对互斥量进行任何操作,查看程序运行情况。图2多线程加锁参考程序:------------------------------------------------------------------------------------------------thread2.c--------------#includeunistd.h#includestdlib.h#includestdio.h#includepthread.h4#includeourhdr.h#includeerror.c//自定义文件,线程创建不成功时输出出错信息structfoo{//结构体foointf_count;pthread_mutex_tf_lock;};structfoo*fp;//定义全局变量fpstructfoo*foo_alloc(void){structfoo*fp;if((fp=(foo*)malloc(sizeof(structfoo)))!=NULL){//初始化分fpfp-f_count=0;if(pthread_mutex_init(&fp-f_lock,NULL)!=0){//初始化互斥锁free(fp);return(NULL);}}return(fp);}void*thr_fn1(void*){//thread1printf(nowinthread1\n);printf(thread1exit\n);pthread_exit((void*)1);//thread1退出}intmain(void){interr;pthread_ttid1;void*tret;fp=foo_alloc();printf(initfp,fp-f_count:%d\n,fp-f_count);err=pthread_create(&tid1,NULL,thr_fn1,(void*)1);if(err!=0)err_quit(can'tcreatethread1:%s\n,strerror(err));//在main线程里创建thread1,thr_fn1是thread1最先执行的函数,当thr_fn1函数返回时,thread1将退出sleep(2);//mian线程sleep2秒/***firstlock****/printf(firstlock:);//主线程第一次对互斥量fp-f_lock加锁if(pthread_mutex_lock(&fp-f_lock)==0){printf(locksuccess!\n);fp-f_count++;fp-f_count++;5printf(firstlock,fp-f_count:%d\n,fp-f_count);}elseprintf(firstlockwrong!\n);/***lockagain****/printf(secondlock:\n);//主线程第二次对互斥量fp-f_lock加锁if(pthread_mutex_lock(&fp-f_lock)==0){printf(lockagainsuccess!\n);fp-f_count++;fp-f_count++;printf(secondlock,fp-f_count:%d\n,fp-f_count);}elseprintf(secondlockwrong!\n);err=pthread_join(tid1,&tret);if(err!=0)err_quit(can'tjoinwiththread1:%s\n,strerror(err));//main通过pthread_join等待thread1退出pthread_mutex_destroy(&fp-f_lock);free(fp);//释放结构体fpprintf(mainthreadexit!\n);//输出main线程退出提示exit(0);//main线程退出}------------------------------------------------------------------------------------------------thread2.c--------------在Linux下用g++(即C++的编译器)进行编译链接,并调试运行,结果如下:请记录结果:实验分析(在结果中分析线程可能的状态,必要时修改程序,加入暂停,以便观察):6两次实验的比较:实验结论:2、多线程对互斥量的操作在多线程编程中,我们通过对互斥量进行加锁来保持共享数据的一致性,但是对互斥量的操作必须谨慎,操作不当便会产生死锁,下面四个实验是分析产生死锁的情况以及如何避免死锁。main线程创建3个线程,thread1,thread2,thread3,thread1对互斥量进行加锁,但不解锁,thread2也对互斥量进行加锁,thread3销毁锁状态。图3多线程加锁流程7图4加锁示意图参考代码:-----------------------------------------------------------------------------------------------pthread1.c--------------#includeunistd.h#includestdlib.h#includestdio.h#includepthread.h#includeourhdr.h#includeerror.cstructfoo{//定义结构体intf_count;pthread_mutex_tf_lock;};structfoo*fp;//定义全局变量fpstructfoo*foo_alloc(void){structfoo*fp;if((fp=(foo*)malloc(sizeof(structfoo)))!=NULL){//初始化fpfp-f_count=0;if(pthread_mutex_init(&fp-f_lock,NULL)!=0){//初始化互斥锁free(fp);return(NULL);}}//printf(fp-f_count:%d\n,fp-f_count);return(fp);}void*thr_fn1(void*){//thread1printf(nowinthread1\n);/***lock****/8if(pthread_mutex_lock(&fp-f_lock)==0){//对互斥量进行加锁printf(thread1locksuccess!\n);fp-f_count++;//改变变量fp-f_count的值fp-f_count++;}elseprintf(lockwrong!\n);printf(thread1fp-f_count:%d\n,fp-f
本文标题:UNIX操作系统实验6
链接地址:https://www.777doc.com/doc-3368401 .html