生產消費問題是一個經典的數學問題,要求生產者---消費者在固定的倉庫空間條件下,生產者每生產一個
產品將占用一個倉庫空間,生產者生產的產品庫存不能越過倉庫的存儲量,消費者每消費一個產品將增加
一個倉庫空間,消費者在倉庫產品為0時不能再消費。
以下使用了兩個信號量,一個用來管理消費者即sem_produce,另一個用來管理生產者即sem_custom,
sem_produce表示當前倉庫可用空間的數量,sem_custom用來表示當前倉庫中產品的數量。
- 對於生產者來說,其需要申請的資源為倉庫中的剩余空間,因此,生產者在生產一個產品前需要申請
sem_produce信號量。當此信號量的值大於0,即有可用空間,將生產產品,並將sem_produce的值減去1
(因為占用了一個空間);同時,當其生產一個產品后,當前倉庫的產品數量增加1,需要將sem_custom信號
量自動加1。
- 對於消費者來說,其需要申請的資源為倉庫中的產品,因此,消費者在消費一個產品前將申請sem_cu
stom信號量。當此信號量的值大於0時,即有可用產品,將消費一個產品,並將sem_custom信號量的值減
去1(因為消費了一個產品);同時,當消費一個產品,當前倉庫的剩余空間增加1,需要將sem_produce信號
量自動加1。
下面是生產者端的代碼:
//sem_productor.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/sem.h> #include <errno.h> #include <sys/types.h> #include <sys/ipc.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("mysem",'s'); sem_id= semget(key,2,IPC_CREAT|0644); sem_array[0]= 0; sem_array[1]= 100; 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,0,IPC_RMID); } 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 is productor\n"); while(1) { printf("\n\nbefore produce:\n"); printf("productor number is %d\n",semctl(sem_id,0,GETVAL)); printf("space number is %d\n",semctl(sem_id,1,GETVAL)); semop(sem_id,(struct sembuf*)&sops[1],1); printf("now producing...\n"); semop(sem_id,(struct sembuf*)&sops[0],1); printf("\nafter produce\n"); printf("space number is %d\n",semctl(sem_id,1,GETVAL)); printf("productor number is %d\n",semctl(sem_id,0,GETVAL)); sleep(2); } del(); return 0; }
下面是消費者端的代碼:
//sem_customer.c #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.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("mysem",'s'); sem_id= semget(key,2,IPC_CREAT|0644); } 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 is customer\n"); while(1) { printf("\n\nbefore consume:\n"); int ret= semctl(sem_id,0,GETVAL); int ret1= semctl(sem_id,1,GETVAL); printf("productor is %d\n",ret); printf("space is %d\n",ret1); semop(sem_id,(struct sembuf*)&sops[0],1); printf("now consuming...\n"); semop(sem_id,(struct sembuf*)&sops[1],1); printf("\nafter consume\n"); printf("productor number is %d\n",semctl(sem_id,0,GETVAL)); printf("space number is %d\n",semctl(sem_id,1,GETVAL)); sleep(3); } return 0; }