生產者 消費者問題實現

2021-06-08 06:51:28 字數 4724 閱讀 4634

#include 

#include 

#include 

#include 

#include 

#include 

#define need_p 2       //生產者程序數

#define need_c 2       //消費者程序數

#define works_p 10    //每個生產者程序執行的次數

#define works_c 10    //每個消費者程序執行的次數

#define buf_length (sizeof(struct mybuffer))     //共享記憶體的大小

#define buf_num  10                         //緩衝區的大小

#define shm_mode  0600

#define sem_all_key  2411

#define sem_empty  0                //空的訊號量

#define sem_full  1                  //滿的訊號量

//緩衝區結構(迴圈佇列)

struct mybuffer

char letter[buf_num];

int head;

int tail;

int is_empty;

//得到

5以內的乙個隨機數

int get_random()

int t;

srand((unsigned)(getpid() + time(null)));

t = rand() % 5;

return t;

//得到

a~z的乙個隨機字母

char get_char()

char a;

srand((unsigned)(getpid() + time(null)));

a = (char)((char)(rand() % 26) + 'a');

return a;

//p操作

void p(int sem_id, int sem_num)  

struct sembuf pc;

pc.sem_num = sem_num;    //訊號量的型別

pc.sem_op = -1;           //操作型別

pc.sem_*** = 0;          //操作的標誌

semop(sem_id, &pc, 1);

//v操作

void v(int sem_id, int sem_num)

struct sembuf pc;

pc.sem_num = sem_num;

pc.sem_op = 1;

pc.sem_*** = 0;

semop(sem_id, &pc, 1);

//主函式

int main(int argc, char * argv)

int i, j;

int shm_id, sem_id;

int num_p = 0, num_c = 0;

struct mybuffer * shmptr;

char lt;

time_t now;

pid_t pid_p, pid_c;      

sem_id = semget(sem_all_key, 2, ipc_creat | 0600);    //建立訊號量,建立的訊號量數量為

2,返回此訊號量的id

if (sem_id >= 0)

printf("main process starts. semaphore created.\n");

semctl(sem_id, sem_empty, setval, buf_num);    //初始設定第乙個訊號量

se_empty

的值為buf_num;

semctl(sem_id, sem_full, setval, 0);          //初始設定第二個訊號量

se_full

的值為0;

if ((shm_id = shmget(ipc_private, buf_length, shm_mode)) < 0)   //分配記憶體共享

printf("error on shmget.\n");

exit(1);

if ((shmptr = shmat(shm_id, 0, 0)) == (void *)-1)           //將共享的記憶體附加到程序的位址空間

printf("error on shmat.\n");

exit(1);

shmptr->head = 0;

shmptr->tail = 0;

shmptr->is_empty = 1;    

while ((num_p++) < need_p)

if ((pid_p = fork()) < 0)   //建立新的程序

printf("error on fork.\n");

exit(1);

//如果是子程序,開始建立生產者

if (pid_p == 0)

if ((shmptr = shmat(shm_id, 0, 0)) == (void *)-1)

printf("error on shmat.\n");

exit(1);

for (i = 0; i < works_p; i++)

p(sem_id, sem_empty);

sleep(get_random());

shmptr->letter[shmptr->tail] = lt = get_char();

shmptr->tail = (shmptr->tail + 1) % buf_num;

shmptr->is_empty = 0;

now = time(null);

printf("%02d:%02d:%02d\t", localtime(&now)->tm_hour, localtime(&now)->tm_min, localtime(&now)->tm_sec);

for (j = (shmptr->tail - 1 >= shmptr->head) ? (shmptr->tail - 1) : (shmptr->tail - 1 + buf_num); !(shmptr->is_empty) && j >= shmptr->head; j--)

printf("%c", shmptr->letter[j % buf_num]);

printf("\tproducer %d puts '%c'.\n", num_p, lt);

fflush(stdout);              //重新整理緩衝區

v(sem_id, sem_full);

shmdt(shmptr);      //分離共享記憶體

exit(0);

while (num_c++ < need_c)

if ((pid_c = fork()) < 0)  //建立新的程序

printf("error on fork.\n");

exit(1);

//如果是子程序,開始建立消費者

if (pid_c == 0)

if ((shmptr = shmat(shm_id, 0, 0)) == (void *)-1)

printf("error on shmat.\n");

exit(1);

for (i = 0; i < works_c; i++)

p(sem_id, sem_full);

sleep(get_random());

lt = shmptr->letter[shmptr->head];

shmptr->head = (shmptr->head + 1) % buf_num;

shmptr->is_empty = (shmptr->head == shmptr->tail);

now = time(null);

printf("%02d:%02d:%02d\t", localtime(&now)->tm_hour, localtime(&now)->tm_min, localtime(&now)->tm_sec);

for (j = (shmptr->tail - 1 >= shmptr->head) ? (shmptr->tail - 1) : (shmptr->tail - 1 + buf_num); !(shmptr->is_empty) && j >= shmptr->head; j--)

printf("%c", shmptr->letter[j % buf_num]);

printf("\tconsumer %d gets '%c'.\n", num_c, lt);

fflush(stdout);

v(sem_id, sem_empty);

shmdt(shmptr);

exit(0);

//主控程式最後退出

while(wait(0) != -1);

shmdt(shmptr);                    //分離共享記憶體

shmctl(shm_id, ipc_rmid, 0);       //撤銷共享記憶體

semctl(sem_id, ipc_rmid, 0);       //釋放記憶體

printf("main process ends.\n");

fflush(stdout);

exit(0);

生產者消費者問題

public class producer consumer class godown public godown int num public synchronized void produce int n catch interruptedexception e curr num n syste...

生產者 消費者問題

在學習程序互斥中,有個著名的問題 生產者 消費者問題。這個問題是乙個標準的 著名的同時性程式設計問題的集合 乙個有限緩衝區和兩類執行緒,它們是生產者和消費者,生產者把產品放入緩衝區,相反消費者便是從緩衝區中拿走產品。生產者在緩衝區滿時必須等待,直到緩衝區有空間才繼續生產。消費者在緩衝區空時必 須等待...

生產者 消費者問題

1 程序互斥問題 緩衝區b是臨界資源,程序p和c不能同時對b進行操作,即只能互斥的操作 2 程序同步問題 p不能往 滿 的的緩衝區b放產品,c不能從空的緩衝區獲得產品。當緩衝區滿時,c必須先於p執行,當緩衝區空時,p必須先於c執行 我們給出如下基於記錄型 二元 訊號量機制的解法 10 9 2013 ...