南昌大学操作系统实验报告二编程模拟进程间的同步和互斥

内容发布更新时间 : 2024/5/18 11:38:42星期一 下面是文章的全部内容请认真阅读。

arg.val = 1;

if(semctl(mutxid , 0 ,SETVAL , arg) == -1) perror(\ //初始化P,V操作 V.sem_num=0; V.sem_op =1;

V.sem_flg=SEM_UNDO; P.sem_num=0; P.sem_op =-1;

P.sem_flg=SEM_UNDO; //生产者进程

if(fork() == 0 ) { int i = 0;

while( i < 100)

{

//semop(信号量,资源,数目) semop(emptyid , &P ,1 ); //mutex实现临界资源的互斥使用 semop(mutxid , &P , 1);

array[*(set)%MAXSEM] = i + 1;

printf(\ //生产产品的标号+1 (*set)++;

semop(mutxid , &V , 1); semop(fullid , &V , 1); i++; }

sleep(10);

printf(\ exit(0); }else {

//ConsumerA 进程 if(fork()==0) {

while(1){ semop(fullid , &P , 1);

semop(mutxid , &P , 1);

//判断是否所有产品都被消费了 if(*get == 100) break;

*sum += array[(*get)%MAXSEM];

printf(\ (*get)++;

//判断这次消费是否为最后一次消费

6

if( *get ==100)

printf(\ semop(mutxid , &V , 1); semop(emptyid , &V ,1 ); sleep(1); }

printf(\ exit(0); }else {

//Consumer B进程 if(fork()==0) { while(1){

semop(fullid , &P , 1); semop(mutxid , &P , 1); if(*get == 100) break;

*sum += array[(*get)%MAXSEM];

printf(\ (*get)++; if( *get ==100)

printf(\ semop(mutxid , &V , 1); semop(emptyid , &V ,1 ); sleep(1); }

printf(\ exit(0); } } }

// sleep(20); return 0; }

7

8

要解决该问题,就必须让生产者在缓冲区满时休眠(要么干脆就放弃数据),等到下次消费者消耗缓冲区中的数据的时候,生产者才能被唤醒,开始往缓冲区添加数据。同样,也可以让消费者在缓冲区空时进入休眠,等到生产者往缓冲区添加数据之后,再唤醒消费者。通常采用进程间通信的方法解决该问题,常用的方法有信号灯法等。如果解决方法不够完善,则容易出现死锁的情况。出现死锁时,两个线程都会陷入休眠,等待对方唤醒自己。该问题也能被推广到多个生产者和消费者的情形。

思考:

1、关于sleep()

Sleep函数对于指定的时间间隔挂起当前的执行线程。 格式:VOID Sleep(DWORD dwMilliseconds ); dwMilliseconds:定义挂起执行线程的时间,以毫秒(ms)为单位。取值为0时,该线程将余下的时间片交给处于就绪状态的同一优先级的其他线程。若没有处于就绪状态的同一优先级的其他线程,则函数立即返回,该线程继续执行。若取值为INFINITE则造成无限延迟。 2.关于semop

在 Linux 下,PV 操作通过调用semop函数来实现。该函数定义在头文件 sys/sem.h中,原型如下:

int semop(int semid,struct sembuf *sops,size_t nsops);

流程图:

9

(三)第三个程序没有调试好

10

联系客服:779662525#qq.com(#替换为@) 苏ICP备20003344号-4 ceshi