我有使用線程和信號量來處理生產者和消費者問題的任務。其任務是允許用戶定義生產者數量,消費者數量和緩衝區大小。如果生產者到達緩衝區大小,程序總是鎖定。但是要求說如果生產者達到緩衝區,消費者線程應該開始並從緩衝區中取出東西。我不知道如何解決這個問題,我的老師拒絕幫助。我完全是C語言的初學者,請給我一些建議。非常感謝C - 當生產者大於緩衝區大小時,消費者/生產者會出現死鎖
當Producer = Consumer或Producer時,我的程序可以運行< Consumer,除Producer> Buffer Size之外,它似乎出現死鎖,並且我想我理解爲什麼但我不知道如何修復代碼讓消費者線程先運行回到生產者線程。
下面是運行結果當製片= 3消費= 1和緩衝區大小= 2
./Task2 3 1 2
Producer 0 has started
Producer 0:Put item 0.
Producer 1 has started
Producer 1:Put item 1.
Producer 2 has started
要求說,結果應該看起來像
Started
Producer 0 has started
Producer 0: Put item 0.
Producer 1 has started
Producer 1: Put item 1.
Producer 2 has started
Consumer 0 has started
Consumer 0: Taked item 0.
Producer 2: Put item 2.
Terminated!
這裏是我的原始代碼,我有丟棄一些輸入錯誤檢查代碼
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
pthread_t *pid, *cid;
void *producer(void *param);
void *consumer(void *param);
void init();
int Remove();
struct prot_buffer{
int Producer;
int Consumer;
int *buffer;
int buffersize;
int front;
int rear;
int item;
sem_t mutex;
sem_t slots;
sem_t items;
}b;
main(int argc, char *argv[]){
int c1;
b.Producer = atoi(argv[1]);
b.Consumer = atoi(argv[2]);
b.buffersize = atoi(argv[3]);
init();
pid = (pthread_t *)malloc(b.Producer *sizeof(pthread_t));
cid = (pthread_t *)malloc(b.Consumer *sizeof(pthread_t));
for (c1=0; c1< b.Producer; c1++){
printf("Producer %d has started\n", c1);
pthread_create(&(pid[c1]),NULL, producer, NULL);
pthread_join(pid[c1], NULL);
printf("Producer %d:Create item %d.\n", c1,c1);
}
/* Create the consumer threads */
for (c1=0; c1<b.Consumer; c1++){
printf("Consumer %d has started\n", c1);
pthread_create(&(cid[c1]),NULL, consumer, NULL);
if (b.front==b.rear){
printf("Terminated!\n");
exit(0);
}
pthread_join(cid[c1], NULL);
printf("Consumer %d:Taked item %d.\n", c1, c1);
}
free(b.buffer);
free(pid);
free(cid);
sem_destroy(&b.items);
sem_destroy(&b.slots);
sem_destroy(&b.mutex);
printf("Threads terminated!\n");
exit(0);
}
void *producer(void *param){
sem_wait(&b.slots); sem_wait(&b.mutex);
if(b.rear<=b.buffersize){
b.buffer[b.rear] = b.item;
b.rear++;
sem_post(&b.mutex); sem_post(&b.items);
}else{
sem_post(&b.mutex); sem_post(&b.items); }
}
void *consumer(void *param){
Remove();
}
void init(){
b.buffer = (int *) malloc(b.buffersize *sizeof(int));
b.buffersize = b.buffersize;
b.front = b.rear =0;
sem_init(&b.items, 0, 0);
sem_init(&b.slots,0,b.buffersize);
sem_init(&b.mutex, 0, 1);
}
int Remove(){
sem_wait(&b.items);
sem_wait(&b.mutex);
b.item = b.buffer[b.front];
b.front++;
sem_post(&b.mutex);
sem_post(&b.slots);
return b.item;
}
我的新代碼
main(int argc, char *argv[]){
...
pthread_create(&pid,NULL, producer, NULL);
pthread_create(&cid,NULL, consumer, NULL);
....
}
void *producer(void *param){
int c2;
for (c2=0; c2 < b.Producer; c2++) {
printf("Producer %d has started\n", c2);
b.item = c2;
sem_wait(&b.slots);
sem_wait(&b.mutex);
b.buffer[b.rear] = b.item;
b.rear = (b.rear+1)%b.buffersize;
printf("Producer %d:Put item %d.\n", c2,c2);
sem_post(&b.mutex);
sem_post(&b.items);
}
return NULL;
}
void *consumer(void *param){
int c2;
for (c2=0; c2 < b.Consumer; c2++) {
printf("Consumer %d has started\n", c2,c2);
b.item = c2;
sem_wait(&b.items);
sem_wait(&b.mutex);
b.buffer[b.front] = b.item;
b.front = (b.front+1)%b.buffersize;
printf("Consumer %d:take item %d.\n", c2, c2);
sem_post(&b.mutex);
sem_post(&b.slots);
}
return NULL;
}
爲了避免學校的流膿,我刪除了一些代碼和一些描述。
程序結果現在正確,謝謝你的幫助。在這種情況下,我使用b.item作爲變量來顯示留在緩衝區內的項目,但它的錯誤。使用其他變量,如前面或後面也不工作。
方案result-
生產者= 2,消費者= 2,緩衝液= 2
./F 2 2 2
started
Producer 0 has started
Producer 0:Put item 0.
Producer 1 has started
Producer 1:Put item 1.
Consumer 0 has started
Consumer 0:Take item 0.
Consumer 1 has started
Consumer 1:Take item 1.
1 item(s) left in the buffer! //This is wrong!
Terminated!
生產者= 3,消費者= 1,緩衝液= 2
./F 3 1 2
started
Producer 0 has started
Producer 0:Deposited item 0.
Producer 1 has started
Producer 1:Deposited item 1.
Producer 2 has started
Consumer 0 has started
Consumer 0:Removed item 0.
Producer 2:Deposited item 2.
0 item(s) left in the buffer! //Still wrong!
Terminated!
生產者= 2 ,Consumer = 5,Buffer = 3
./F 2 5 3
started
Producer 0 has started
Producer 0:Put item 0.
Producer 1 has started
Producer 1:Put item 1.
Consumer 0 has started
Consumer 0:Take item 0.
Consumer 1 has started
Consumer 1:Take item 1.
Consumer 2 has started
2 item(s) left in the buffer! //Wrong again!
Terminated!
投射'malloc'的返回值是不必要的。 – 2012-03-27 09:56:50
你是否被限制使用信號量?你不能使用條件變量嗎?他們似乎是這種情況下更自然的選擇。 – Tudor 2012-03-27 10:02:14
@Tudor是的,任務的要求表示我們必須使用信號量。 – 2012-03-27 10:16:27