内容发布更新时间 : 2024/11/1 7:51:15星期一 下面是文章的全部内容请认真阅读。
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