ImageVerifierCode 换一换
格式:DOCX , 页数:27 ,大小:300.95KB ,
资源ID:10876415      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/10876415.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(linux多线程实验报告.docx)为本站会员(b****8)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

linux多线程实验报告.docx

1、linux多线程实验报告实验八 Linux多线程实验报告撰写人专业班级学号完成时间。一、实验目的1、了解什么是多线程,熟悉LINUX的多线程机制;2、掌握利用信号处理Linux多线程的同步问题;3、掌握利用信号量处理Linux多线程的互斥问题;4、运用Linux多线程的同步机制和互斥机制实现生产者消费者的编程。二、实验内容1“生产者-消费者”问题如下:有一个有限缓冲区和两个线程:生产者和消费者。他们分别不停地把产品放入缓冲区、从缓冲区中拿走产品。一个生产者在缓冲区满的时候必须等待,一个消费者在缓冲区空的时候也必须等待。另外,因为缓冲区是临界资源,所以生产者和消费者之间必须互斥执行。它们之间的关

2、系如图1所示。现在要求使用共享内存来模拟有限缓冲区,并且使用信号量来解决“生产者-消费者”问题中的同步和互斥问题。1 生产者和消费者问题描述2. 问题描述:假设有五位哲学家围坐在一张圆形餐桌旁,做以下两件事情之一:吃饭,或者思考。吃东西的时候,他们就停止思考,思考的时候也停止吃东西。餐桌中间有一大碗意大利面,每两个哲学家之间有一只餐叉。因为用一只餐叉很难吃到意大利面,所以假设哲学家必须用两只餐叉吃东西。他们只能使用自己左右手边的那两只餐叉。请用Linux线程编程解决。2 哲学家进餐问题示意图三、实验过程与结果操作过程错误解决方法实验1步骤一:编写producer_customer.c的文件在不

3、同的编译器中for循环的用法不太一样,在这里最好不要使用for(int i=0; ;)最好在外声明int i在for循环里直接写i=0步骤二:编译代码并且运行代码步骤三:运行完毕后,显示以下代码:生产者消费者先后生产数据以及取出数据,此程序中设置了两个消费者两个生产者,交替进行生产数据消费数据。实验2步骤一:编写philosopher.c的文件步骤二:编译代码并且运行代码步骤三:实验代码实验一:#include #include #include #include #include #include #include #include #define MAX_BUFFER_SIZE 10#de

4、fine SHM_MODE 0600#define SEM_MODE 0600#define SEM_FULL 0#define SEM_EMPTY 1#define MUTEX 2/*#if defined(_GNU_LIBRARY_) & !defined(_SEM_SEMUN_UNDEFINED)/ union semun is defined by including #else/ according to X/OPEN we have to define it ourselvesunion semunint val;struct semid_ds *buf;unsigned shor

5、t *array;#endifunion semun su;/sem union,用于初始化信号量*/struct my_buffer int head; int tail; char strMAX_BUFFER_SIZE; int num; /缓冲区里字母数量 int is_empty;const int N_CONSUMER = 2;/消费者数量const int N_PRODUCER = 2;/生产者数量const int N_BUFFER = 10;/缓冲区容量const int N_WORKTIME = 10;/工作次数int shm_id = -1;int sem_id = -1;

6、pid_t child;pid_t parent;/得到10以内的一个随机数int get_random() int digit; srand(unsigned)(getpid() + time(NULL); digit = rand() % 10; return digit;/得到AZ的一个随机字母char getRandChar() char letter; srand(unsigned)(getpid() + time(NULL); letter = (char)(rand() % 26) + A); return letter;/sem_id 表示信号量集合的 id/sem_num 表

7、示要处理的信号量在信号量集合中的索引/P操作void waitSem(int sem_id,int sem_num) struct sembuf sb; sb.sem_num = sem_num; sb.sem_op = -1;/表示要把信号量减一 sb.sem_flg = SEM_UNDO;/第二个参数是 sembuf 类型的,表示数组/第三个参数表示 第二个参数代表的数组的大小 if(semop(sem_id,&sb,1) 0) perror(waitSem failed); exit(1); /V操作void sigSem(int sem_id,int sem_num) struct s

8、embuf sb; sb.sem_num = sem_num; sb.sem_op = 1; sb.sem_flg = SEM_UNDO; /第二个参数是 sembuf 类型的,表示数组 /第三个参数表示 第二个参数代表的数组的大小 if(semop(sem_id,&sb,1) 0) perror(sigSem failed); exit(1); /打印进程运行结果void printTime() /打印时间 time_t now; struct tm *timenow; /实例化tm结构指针 time(&now); timenow = localtime(&now); printf(执行时间

9、: %s ,asctime(timenow);int main(int argc, char * argv) shm_id = shmget(IPC_PRIVATE,MAX_BUFFER_SIZE,SHM_MODE); /申请共享内存 if(shm_id 0) perror(create shared memory failed); exit(1); struct my_buffer *shmptr; shmptr = shmat(shm_id, 0, 0); /将申请的共享内存附加到申请通信的进程空间 if (shmptr = (void*)-1) perror(add buffer to

10、using process space failed!n); exit(1); if(sem_id = semget(IPC_PRIVATE,3,SEM_MODE) SEM_FULL perror(sem set value error! n); exit(1); if(semctl(sem_id,SEM_EMPTY,SETVAL,10) = -1) /将索引为1的信号量设置为10-SEM_EMPTY perror(sem set value error! n); exit(1); if(semctl(sem_id,MUTEX,SETVAL,1) = -1) /将索引为3的信号量设置为1-MU

11、TEX perror(sem set value error! n); exit(1); shmptr - head = 0; shmptr - tail = 0; shmptr - is_empty = 1; shmptr - num = 0; int i; for(i = 0; i N_PRODUCER; i+) parent = fork(); if(parent 0) perror(the fork failed); exit(1); else if(parent = 0) shmptr = shmat(shm_id, 0, 0); /将申请的共享内存附加到申请通信的进程空间 if (

12、shmptr = (void*)-1) perror(add buffer to using process space failed!n); exit(1); int count = 0; int j; for(j = 0; j strshmptr-tail = c; shmptr - tail = (shmptr-tail + 1) % MAX_BUFFER_SIZE; shmptr - is_empty = 0; /写入新产品 shmptr - num+; /*打印输出结果*/ printTime(); /程序运行时间 int p; printf(缓冲区数据(%d个):,shmptr -

13、 num); /打印缓冲区中的数据 p = (shmptr-tail-1 = shmptr-head) ? (shmptr-tail-1) : (shmptr-tail-1 + MAX_BUFFER_SIZE); for (p; !(shmptr - is_empty) & p = shmptr - head; p-) printf(%c, shmptr - strp % MAX_BUFFER_SIZE); printf(t 生产者 %d 放入 %c. n, i + 1, c); printf(-n); fflush(stdout); sigSem(sem_id, MUTEX); sigSem

14、(sem_id, SEM_FULL); /将共享段与进程之间解除连接 shmdt(shmptr); exit(0); for(i = 0; i N_CONSUMER; i+) child = fork(); if(child 0)/调用fork失败 perror(the fork failed); exit(1); else if(child = 0) int count = 0; shmptr = shmat(shm_id, 0, 0); /将申请的共享内存附加到申请通信的进程空间 if (shmptr = (void*)-1) perror(add buffer to using proc

15、ess space failed!n); exit(1); int j; for(j = 0; j strshmptr - head; shmptr - head = (shmptr - head + 1) % MAX_BUFFER_SIZE; shmptr - is_empty = (shmptr-head = shmptr-tail); / shmptr - num-; /*打印输出结果*/ printTime(); /程序运行时间 int p; printf(缓冲区数据(%d个):,shmptr - num); /打印缓冲区中的数据 p = (shmptr - tail - 1 = sh

16、mptr - head) ? (shmptr - tail-1) : (shmptr - tail - 1 + MAX_BUFFER_SIZE); for (p; !(shmptr - is_empty) & p = shmptr - head; p-) printf(%c, shmptr - strp % MAX_BUFFER_SIZE); printf(t 消费者 %d 取出 %c. n, i + 1, lt); printf(-n); fflush(stdout); sigSem(sem_id,MUTEX); sigSem(sem_id,SEM_EMPTY); /将共享段与进程之间解除连

17、接 shmdt(shmptr); exit(0); /主进程最后退出 while (wait(0) != -1); /将共享段与进程之间解除连接 shmdt(shmptr); /对共享内存区执行控制操作 shmctl(shm_id,IPC_RMID,0);/当cmd为IPC_RMID时,删除该共享段 shmctl(sem_id,IPC_RMID,0); printf(主进程运行结束!n); fflush(stdout); exit(0); return 0;实验二:#include#include#include#include#include#include#include#define N

18、 5 /哲学家数量#define LEFT(i) (i+N-1)%N /左手边哲学家编号#define RIGHT(i) (i+1)%N /右手边哲家编号#define HUNGRY 0 /饥饿#define THINKING 1 /思考#define EATING 2 /吃饭#define U_SECOND 1000000 /1秒对应的微秒数pthread_mutex_t mutex; /互斥量int stateN; /记录每个哲学家状态/每个哲学家的思考时间,吃饭时间,思考开始时间,吃饭开始时间clock_t thinking_timeN, eating_timeN, start_eati

19、ng_timeN, start_thinking_timeN; /线程函数void *thread_function(void *arg);int main() pthread_mutex_init(&mutex, NULL); pthread_t a,b,c,d,e; /为每一个哲学家开启一个线程,传递哲学家编号 pthread_create(&a,NULL,thread_function,0); pthread_create(&b,NULL,thread_function,1); pthread_create(&c,NULL,thread_function,2); pthread_crea

20、te(&d,NULL,thread_function,3); pthread_create(&e,NULL,thread_function,4); /初始化随机数种子 srand(unsigned int)(time(NULL); while(1) ; void *thread_function(void *arg) char *a = (char *)arg; int num = a0 - 0; /根据传递参数获取哲学家编号 int rand_time; while(1) /关键代码加锁 pthread_mutex_lock(&mutex); /如果该哲学家处于饥饿 并且 左右两位哲学家都没

21、有在吃饭 就拿起叉子吃饭 if(statenum = HUNGRY & stateLEFT(num) != EATING & stateRIGHT(num) != EATING) statenum = EATING; start_eating_timenum = clock(); /记录开始吃饭时间 eating_timenum = (rand() % 5 + 5) * U_SECOND; /随机生成吃饭时间 /输出状态 printf(state: %d %d %d %d %dn,state0,state1,state2,state3,state4); /printf(%d is eating

22、n,num); else if(statenum = EATING) /吃饭时间已到 ,开始思考 if(clock() - start_eating_timenum = eating_timenum) / statenum = THINKING; /printf(%d is thinkingn,num); printf(state: %d %d %d %d %dn,state0,state1,state2,state3,state4); start_thinking_timenum = clock(); /记录开始思考时间 thinking_timenum = (rand() % 10 + 1

23、0) * U_SECOND; /随机生成思考时间 else if(statenum = THINKING) /思考一定时间后,哲学家饿了,需要吃饭 if(clock() - start_thinking_timenum = thinking_timenum) statenum = HUNGRY; printf(state: %d %d %d %d %dn,state0,state1,state2,state3,state4); / printf(%d is hungryn,num); pthread_mutex_unlock(&mutex); 四、实验小结生产者消费者问题(英语:Produce

24、r-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同步问题的经典案例。该问题描述了两个共享固定大小缓冲区的线程即所谓的“生产者”和“消费者”在实际运行时会发生的问题。生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程。与此同时,消费者也在缓冲区消耗这些数据。该问题的关键就是要保证生产者不会在缓冲区满时加入数据,消费者也不会在缓冲区中空时消耗数据。1) 关系分析。生产者和消费者对缓冲区互斥访问是互斥关系,同时生产者和消费者又是一个相互协作的关系,只有生产者生产之后,消费者才能消费,他们也是同步关系。2) 整理思路。这里比较简单,只有生产者和消费者两个进程,正好是这两个进程存在着互斥关系和同步关系。那么需要解决的是互斥和同步PV操作的位置。3) 信号量设置。信号量mutex作为互斥信号量,它用于控制互斥访问缓冲池,互斥信号量初值为1;信号量full用于记录当前缓冲池中“满”缓冲区数,初值为0。信号量empty 用于记录当前缓冲池中“空”缓冲区数,初值为n。

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1