我的代码只用于一个生产者 - 一个消费者的情况。pthread_cond_wait fifo循环队列中的死锁
这里是我的测试代码:
static void *afunc(void * arg) {
Queue* q = arg;
for(int i= 0; i< 100000; i++) {
*queue_pull(q) = i; //get one element space
queue_push(q); //increase the write pointer
}
return NULL;
}
static void *bfunc(void * arg) {
Queue* q = arg;
for(;;) {
int *i = queue_fetch(q); //get the first element in queue
printf("%d\n", *i);
queue_pop(q); //increase the read pointer
}
}
int main() {
Queue queue;
pthread_t a, b;
queue_init(&queue);
pthread_create(&a, NULL, afunc, &queue);
pthread_create(&b, NULL, bfunc, &queue);
sleep(100000);
return 0;
}
,这里是循环队列
#define MAX_QUEUE_SIZE 3
typedef struct Queue{
int data[MAX_QUEUE_SIZE] ;
int read,write;
pthread_mutex_t mutex, mutex2;
pthread_cond_t not_empty, not_full;
}Queue;
int queue_init(Queue *queue) {
memset(queue, 0, sizeof(Queue));
pthread_mutex_init(&queue->mutex, NULL);
pthread_cond_init(&queue->not_empty, NULL);
pthread_mutex_init(&queue->mutex2, NULL);
pthread_cond_init(&queue->not_full, NULL);
return 0;
}
int* queue_fetch(Queue *queue) {
int* ret;
if (queue->read == queue->write) {
pthread_mutex_lock(&queue->mutex);
pthread_cond_wait(&queue->not_empty, &queue->mutex);
pthread_mutex_unlock(&queue->mutex);
}
ret = &(queue->data[queue->read]);
return ret;
}
void queue_pop(Queue *queue) {
nx_atomic_set(queue->read, (queue->read+1)%MAX_QUEUE_SIZE);
pthread_cond_signal(&queue->not_full);
}
int* queue_pull(Queue *queue) {
int* ret;
if ((queue->write+1)%MAX_QUEUE_SIZE == queue->read) {
pthread_mutex_lock(&queue->mutex2);
pthread_cond_wait(&queue->not_full, &queue->mutex2);
pthread_mutex_unlock(&queue->mutex2);
}
ret = &(queue->data[queue->write]);
return ret;
}
void queue_push(Queue *queue) {
nx_atomic_set(queue->write, (queue->write+1)%MAX_QUEUE_SIZE);
pthread_cond_signal(&queue->not_empty);
}
后片刻的实施,似乎两个子线程会变成僵局..
编辑:我使用两个信号量,但它也有一些问题..它很漂亮 奇怪,如果只是执行./main,它似乎很好,但如果我重定向到一个文件,如./main> A.TXT,然后WC -l A.TXT,结果不等于所述排队号码..
int queue_init(Queue *queue) {
memset(queue, 0, sizeof(Queue));
pthread_mutex_init(&queue->mutex, NULL);
sem_unlink("/not_empty");
queue->not_empty = sem_open("/not_empty", O_CREAT, 644, 0);
sem_unlink("/not_full");
queue->not_full = sem_open("/not_full", O_CREAT, 644, MAX_QUEUE_SIZE);
return 0;
}
int* queue_fetch(Queue *queue) {
sem_wait(queue->not_empty);
return &(queue->data[queue->read]);
}
void queue_pop(Queue *queue) {
nx_atomic_set(queue->read, (queue->read+1)%MAX_QUEUE_SIZE);
sem_post(queue->not_full);
}
int* queue_pull(Queue *queue) {
sem_wait(queue->not_full);
return &(queue->data[queue->write]);
}
void queue_push(Queue *queue) {
nx_atomic_set(queue->write, (queue->write+1)%MAX_QUEUE_SIZE);
sem_post(queue->not_empty);
}
pthreads条件不是标志......它们不保留“设置”。如果您没有等待*条件发出信号*,您将错过信号。 – Dmitri 2014-10-11 05:46:45
更好的解决方案吗?一个sem_t是不够的 – user3682618 2014-10-11 06:03:11
如果你打算使用信号量,一个sem_t和一个互斥对于一个无界队列就足够了(对任何数量的生产者/消费者来说都是安全的)。如果你需要一个有界的队列,你需要另一个sem_t。 – 2014-10-11 13:21:03