Linux信号量机制

时间:2021-06-24 15:04:46


1.编写生产者代码:

用gedit完成productor.c的编写:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <errno.h>
int sem_id;

void init()
{
key_t key;
int ret;
unsigned short sem_array[2];
union semun
{
int val;
struct semid_ds *buf;
unsigned short *array;
}arg;
key=ftok(".",'s');
sem_id=semget(key,2,IPC_CREAT|0644);
sem_array[0]=0; //identify the productor
sem_array[1]=100; //identifythe space
arg.array = sem_array;
ret = semctl(sem_id, 0, SETALL,arg);
if (ret == -1)
{
printf("SETALL failed(%d)\n", errno);
}
printf("productor init is%d\n",semctl(sem_id,0,GETVAL));
printf("space init is%d\n\n",semctl(sem_id,1,GETVAL));

}
void del()
{
semctl(sem_id,IPC_RMID,0);
}

int main(int argc,char *argv[])
{
struct sembuf sops[2];
sops[0].sem_num = 0;
sops[0].sem_op = 1;
sops[0].sem_flg = 0;
sops[1].sem_num = 1;
sops[1].sem_op = -1;
sops[1].sem_flg = 0;

init();
printf("this isproductor\n");
while(1)
{
printf("\n\nbeforeproduce:\n");
printf("productornumber is %d\n",semctl(sem_id,0,GETVAL));
printf("space numberis %d\n",semctl(sem_id,1,GETVAL));
semop(sem_id,(struct sembuf *)&sops[1],1); //get the space to instore 。the productor
printf("nowproducing......\n");
semop(sem_id,(struct sembuf *)&sops[0],1); //now tell the customer can bucusume
printf("\nafterproduce\n");
printf("spaces numberis %d\n",semctl(sem_id,1,GETVAL));
printf("productornumber is %d\n",semctl(sem_id,0,GETVAL));
sleep(2);
}
del();
}
2.编写消费者代码:
用gedit完成sem.c的编写:

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <errno.h>
int sem_id;

void init()
{
key_t key;
key=ftok(".",'s');
sem_id=semget(key,2,IPC_CREAT|0644);
//printf("sem id is%d\n",sem_id);
}
int main(int argc,char *argv[])
{
init();
struct sembuf sops[2];
sops[0].sem_num = 0;
sops[0].sem_op = -1;
sops[0].sem_flg = 0;
sops[1].sem_num = 1;
sops[1].sem_op = 1;
sops[1].sem_flg = 0;
init();

printf("this iscustomer\n");
while(1)
{
printf("\n\nbeforeconsume:\n");
printf("productor is%d\n",semctl(sem_id,0,GETVAL));
printf("space is %d\n",semctl(sem_id,1,GETVAL));
semop(sem_id,(struct sembuf *)&sops[0],1); //get the productor to cusume
printf("nowconsuming......\n");
semop(sem_id,(struct sembuf *)&sops[1],1); //now tell the productor can doproduce
printf("\nafterconsume\n");
printf("productsnumber is %d\n",semctl(sem_id,0,GETVAL));
printf("space numberis %d\n",semctl(sem_id,1,GETVAL));
sleep(2);
}
}

 

3. 讨论问题

1. 编译并运行上述程序,观察运行效果并解释原因?

Linux信号量机制

生产者和消费者对缓冲区互斥访问是互斥关系,同时生产者和消费者又是一个相互协作的关系,只有生产者生产之后,消费者才能消费,他们也是同步关系。

2. 上述代码中,标黄的部分分别是什么意义?

用信号量来标记空间

通过调用semop函数来实现pv操作

Sleep表示生产或消费所需时间

3. 改变生产者、消费者的两项sleep的参数,观察两个进程的运行效果如何改变?

Linux信号量机制

生产与消费不会保持平衡,货品会越来越多(少)

4. 如果同时运行多个生产者、消费者进程,执行情况如何?

Linux信号量机制

可以等效的看成是sleep的数值不一,生产的数量和消费的数量不相称。