我有两个主题。 一个从队列中读取的。我不希望它在(1)读取时运行,因此我正在考虑为每个循环赋予它一个条件变量:
while(1){
while queue is not empty
wait(cond)
pop()
}
而不是:
while(1){
while queue is not empty
pop
}
和一个推送到队列的线程。如果我使用wait和signal方法,那么该线程需要通过每次发送弹出线程来通知(!)它推送 问题是什么更好用? 如果队列大部分都不是空的,那么发送信号是没有价值的(或者不是?)因为弹出线程没有等待,我担心它会降低性能。 但是,如果队列的时间是空的一半,那么在第二个方法中循环播放它可能是一个繁忙的等待。
我希望有人在这里消除我的恐惧,取消将一个信号发送到一个没有等待它的线程仍然可以的事实
由于
答案 0 :(得分:0)
首先,为了确保pthread_cond_signal
不会在signal
意义上发送signal(2)
。它只是标记条件变量并释放正在等待它的任何变量。因此,如果您在消费流程调用之前调用pthread_cond_signal
,那么这将被忽略。
其次,pthread_cond_wait是快还是慢?这得看情况。你可以很好地使用它,你可以很好地使用它。如果你使用得不好,我相信它会表现得非常糟糕。如果你只是在实际需要时等待,我认为它会表现得很好。
因此,由于您需要持有互斥锁以使用条件变量,因此您还可以检查此时是否存在数据(并将此互斥锁用作同步点)。
队列数据结构的想法:
struct q {
struct qe *h;
struct qe *t;
pthread_mutex_t m;
pthread_cond_t c;
int len;
};
消费者(假设您只有一个消费者,如果您有多个消费者需要锁定头部检查):
void *consumer(void*arg) {
struct q *q = arg;
while(1) {
pthread_mutex_lock(&q->m);
if(q->h == NULL)
pthread_cond_wait(&q->c, &q->m);
/* We hold the mutex when we exit pthread_cond_wait */
pthread_mutex_unlock(&q->m); /* we can make the check without the mutex */
while(q->h != NULL) {
pthread_mutex_lock(&q->m); /* but we need it to modify */
pop();
pthread_mutex_unlock(&q->m);
/* Process data */
}
}
}
制片人:
void *producer(void*arg) {
int i;
struct q *q = arg;
while(1) {
pthread_mutex_lock(&q->m);
push(q, some_data);
if(q->h == q->t) /* only one element */
pthread_cond_signal(&q->c);
pthread_mutex_unlock(&q->m);
}
return NULL;
}