#include "pc.h"
#include <stdlib.h>
#include <string.h>
/**
Contents of pc.h
#ifndef __PC__H
#define __PC__H
#include <pthread.h>
#define ITEM(q, i) (q->pc_buffer + q->pc_item_size * i)
struct pc_queue_t {
void *pc_buffer;
size_t pc_next_full, pc_next_empty, pc_cur_size, pc_max_size, pc_item_size;
pthread_cond_t pc_empty, pc_full;
pthread_mutex_t pc_mutex;
};
struct pc_queue_t *alloc_q(size_t item_size, size_t no_of_items);
void pc_insert(struct pc_queue_t *q, void *item);
void *pc_remove(struct pc_queue_t *q);
void free_queue(struct pc_queue_t *q);
#endif
**/
struct pc_queue_t *alloc_q(size_t item_size, size_t no_of_items) {
struct pc_queue_t *q = (struct pc_queue_t *)malloc(sizeof(struct pc_queue_t));
q->pc_buffer = malloc(item_size * no_of_items);
q->pc_next_full = q->pc_next_empty = q->pc_cur_size = 0;
q->pc_item_size = item_size;
q->pc_max_size = no_of_items;
// q->pc_empty = PTHREAD_COND_INITIALIZER;
// q->pc_full = PTHREAD_COND_INITIALIZER;
// q->pc_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_init(&q->pc_empty, NULL);
pthread_cond_init(&q->pc_full, NULL);
pthread_mutex_init(&q->pc_mutex, NULL);
return q;
}
void pc_insert(struct pc_queue_t *q, void *item) {
pthread_mutex_lock(&q->pc_mutex);
while(q->pc_cur_size == q->pc_max_size)
pthread_cond_wait(&q->pc_empty, &q->pc_mutex);
q->pc_cur_size++;
memcpy(ITEM(q, q->pc_next_empty), item, q->pc_item_size);
q->pc_next_empty = (q->pc_next_empty + 1) % q->pc_max_size;
pthread_mutex_unlock(&q->pc_mutex);
pthread_cond_signal(&q->pc_full);
}
void *pc_remove(struct pc_queue_t *q) {
pthread_mutex_lock(&q->pc_mutex);
while(q->pc_cur_size == 0)
pthread_cond_wait(&q->pc_full, &q->pc_mutex);
q->pc_cur_size--;
void *ret_item = ITEM(q, q->pc_next_full);
q->pc_next_full = (q->pc_next_full + 1) % q->pc_max_size;
pthread_mutex_unlock(&q->pc_mutex);
pthread_cond_signal(&q->pc_empty);
return ret_item;
}
void free_queue(struct pc_queue_t *q) {
if(!q) return;
free(q->pc_buffer);
free(q);
}
我试图用c中的互斥和条件变量来解决生产者 - 消费者同步问题。而且我被卡住了。有人可以帮我弄清楚上面给出的代码有什么问题。 pc_insert方法效果很好。但由于某种原因,pc_remove方法永远不会从它的第一次调用返回。可能是什么问题?
这就是我使用它的方式 - &gt;
typedef struct pc_queue_t shared_q;
void *consumer(void *buf) {
shared_q *q = (shared_q *)buf;
while(true) {
int *p = (int *)pc_remove(q);
printf("Removed %d\n", *p);
free(p);
sleep(1);
}
return NULL;
}
void *producer(void *buf) {
shared_q *q = (shared_q *)buf;
int data = 0;
while(true) {
int *p = (int *)malloc(sizeof(int));
*p = data++;
pc_insert(q, p);
printf("Inserted %d\n", data);
sleep(1);
}
return NULL;
}
int main() {
shared_q *q = alloc_q(sizeof(int), 5);
pthread_t t1, t2;
int succ = pthread_create(&t1, NULL, producer, q) &&
pthread_create(&t2, NULL, consumer, q);
if(succ) {
perror("Failed to create threads!");
exit(1);
}
pthread_join(t1, NULL);
pthread_join(t2, NULL);
return 0;
}
答案 0 :(得分:1)
哎呀..我想我明白了。 这就是这条线..
int succ = pthread_create(&t1, NULL, producer, q) &&
pthread_create(&t2, NULL, consumer, q);
我忘了pthread_create在成功时返回0。消费者从未因短路而开始。