我正在尝试使用C中的pthread
来实现生产者/消费者问题。我有一个全局变量int num_available
作为我的两个条件变量fill
和{{1}的状态变量}}
这是我的生产者代码,它应该填补工作和信号消费者。
empty
这是我的消费者代码,它应该完成工作并告知消费者。
void *producer(void *arg){
// Parse the arguments
struct producer_arg_struct *real_arg = (struct producer_arg_struct*) arg;
char *data = real_arg -> data;
size_t filesize = real_arg -> filesize;
// Start the producer loop
while(cur_chunk < data + filesize){
pthread_mutex_lock(&mutex);
printf("producer got lock, items: %d\n", num_available);
// Wait for consumers
while(num_available == MAX){
printf("producer: sleep\n");
pthread_cond_wait(&empty, &mutex);
}
// At least one work to fill
cur_chunk += CHUNK_SIZE;
cur_result++;
num_available++;
pthread_cond_signal(&fill);
pthread_mutex_unlock(&mutex);
}
return NULL;
}
我的程序会陷入无限循环。有两种输出情况:
制作人首先获得锁定:
void *consumer(void *arg){
while(1){
pthread_mutex_lock(&mutex);
printf("consumer: got lock, item: %d\n", num_available);
while(num_available == 0){
// No works available
printf("consumer: sleep\n");
pthread_cond_wait(&fill, &mutex);
}
// Having at least one work available, do the work
num_available--;
compress(cur_chunk, cur_result);
// Signal producer
pthread_cond_signal(&empty);
pthread_mutex_unlock(&mutex);
}
return NULL;
}
消费者首先获得锁定:
producer got lock, items: 0
consumer: got lock, item: 1
consumer: got lock, item: 0
consumer: sleep
consumer: sleep
consumer: sleep
...
consumer: got lock, item: 0
consumer: sleep
consumer: sleep
consumer: sleep
...
中的pthread_cond_wait(&fill, &mutex)
调用似乎确实无法释放锁定或让该消费者入睡。相反,它陷入了无限循环。
我该如何解决?任何建议将不胜感激。
答案 0 :(得分:1)
我希望这可以帮到你。 生产者和消费者线程问题。
#include <stdio.h>
#include <pthread.h>
#define MAX 10000000000
//#define MAX 10
pthread_mutex_t the_mutex;
pthread_cond_t condc, condp;
int maxbuf=5 ; // max produce count.
int buffer = 0;
void* producer(void *ptr) {
int i;
for (i = 1; i <= MAX; i++) {
pthread_mutex_lock(&the_mutex); /* protect buffer */
printf("produce:get lock\n") ;
if(buffer==maxbuf) {
printf("produce:wait! maxbuffer.\n") ;
pthread_cond_wait(&condp, &the_mutex);
printf("produce:wake--\n") ;
}
buffer++;
printf("produce: buffer=%d\n", buffer) ;
pthread_cond_signal(&condc); /* wake up consumer */
pthread_mutex_unlock(&the_mutex);
usleep(rand()%100);
}
pthread_exit(0);
}
void* consumer(void *ptr) {
int i;
for (i = 1; i <= MAX; i++) {
pthread_mutex_lock(&the_mutex);
printf("consume:get lock\n") ;
if (buffer == 0) /* If there is nothing in the buffer then wait */
{
printf("consume: wait! empty.\n") ;
pthread_cond_wait(&condc, &the_mutex);
printf("consume: wake--.\n") ;
}
buffer--;
printf("consume: buffer=%d\n", buffer) ;
pthread_cond_signal(&condp); /* wake up producer */
pthread_mutex_unlock(&the_mutex);
usleep(rand()%100);
}
pthread_exit(0);
}
int main(int argc, char **argv) {
pthread_t pro, con;
// Initialize the mutex and condition variables
/* What's the NULL for ??? */
pthread_mutex_init(&the_mutex, NULL);
pthread_cond_init(&condc, NULL); /* Initialize consumer condition variable */
pthread_cond_init(&condp, NULL); /* Initialize producer condition variable */
// Create the threads
pthread_create(&con, NULL, consumer, NULL);
pthread_create(&pro, NULL, producer, NULL);
// Wait for the threads to finish
// Otherwise main might run to the end
// and kill the entire process when it exits.
pthread_join(con, NULL);
pthread_join(pro, NULL);
// Cleanup -- would happen automatically at end of program
pthread_mutex_destroy(&the_mutex); /* Free up the_mutex */
pthread_cond_destroy(&condc); /* Free up consumer condition variable */
pthread_cond_destroy(&condp); /* Free up producer condition variable */
}
输出是这个...... 双线竞赛。
consume:get lock
consume: buffer=2
produce:get lock
produce: buffer=3
produce:get lock
produce: buffer=4
consume:get lock
consume: buffer=3
consume:get lock
consume: buffer=2
produce:get lock
如果为空
produce:get lock
produce: buffer=1
consume:get lock
consume: buffer=0
consume:get lock
consume: wait! empty.
produce:get lock
produce: buffer=1
consume: wake--.
consume: buffer=0
produce:get lock
produce: buffer=1
consume:get lock
如果产生最大值。
produce:get lock
produce: buffer=5
consume:get lock
consume: buffer=4
produce:get lock
produce: buffer=5
produce:get lock
produce:wait! maxbuffer.
consume:get lock
consume: buffer=4
produce:wake--
produce: buffer=5
produce:get lock