注释下段代码void put(struct prodcons * b, int data) { pthread_mutex_lock(&b->lock);//上锁 /*等待缓冲区非满*/ if (b->writepos == 0){ printf("第十七个数,wait for not full\n"); pthread_cond_signal(&b->notempty); pthread_cond_wait(&b->notfull,&b->lock); } /*写数据并且指针前移*/ b->buffer[b->writepos] = data; b->writepos++; if (b->writepos >= BUFFER_SIZE) b->writepos = 0; /*设置缓冲区非空信号*/ pthread_mutex_unlock(&b->lock); if (data == -1){ printf("最后,生产任务结束\n"); pthread_cond_signal(&b->notempty); } } /*--------------------------------------------------------*/ /*从缓冲区中读出一个整数 */ int get(struct prodcons * b) { int data; pthread_mutex_lock(&b->lock); /* 等待缓冲区非空*/ if (0 == b->readpos){ pthread_cond_signal(&b->notfull); pthread_cond_wait(&b->notempty,&b->lock); printf("wait for not empty\n"); } /* 读数据并且指针前移 */ data = b->buffer[b->readpos]; b->readpos++; if (b->readpos >= (BUFFER_SIZE)) b->readpos = 0; /* 设置缓冲区非满信号*/ pthread_mutex_unlock(&b->lock); return data; } /*--------------------------------------------------------*/ #define OVER (-1) struct prodcons buffer; /*--------------------------------------------------------*/ void * producer(void * data) { int n; for (n = 0; n <= 96; n++) { printf(" put-->%d\n", n); put(&buffer, n); } put(&buffer, OVER); printf("producer stopped!\n"); return NULL; } /*--------------------------------------------------------*/ void * consumer(void * data) { int d; while (1) { d = get(&buffer); if (d == OVER ) break; printf(" %d-->get\n", d); } printf("consumer stopped!\n"); return NULL; } /*--------------------------------------------------------*/ int main(void) { pthread_t th_a, th_b; void * retval; init(&buffer); pthread_create(&th_a, NULL, producer, 0); pthread_create(&th_b, NULL, consumer, 0); /* 等待生产者和消费者结束 */ pthread_join(th_a, &retval); pthread_join(th_b, &retval); return 0; }
时间: 2023-08-15 11:08:59 浏览: 93
这是一个生产者-消费者模型的多线程程序,使用了互斥锁和条件变量来实现线程之间的同步。生产者线程通过put函数往缓冲区中写数据,而消费者线程通过get函数从缓冲区中读数据。
在put函数中,首先使用互斥锁进行上锁,然后判断缓冲区是否已满,如果已满则通过条件变量b->notfull等待缓冲区非满的信号。如果缓冲区非满,则将数据写入缓冲区,并将写指针前移。如果写指针已经到达缓冲区末尾,则将其置为0。最后解锁互斥锁,并根据数据是否为-1来发送缓冲区非空的信号。
在get函数中,也首先使用互斥锁进行上锁,然后判断缓冲区是否为空,如果为空则通过条件变量b->notempty等待缓冲区非空的信号。如果缓冲区非空,则从缓冲区中读取数据,并将读指针前移。如果读指针已经到达缓冲区末尾,则将其置为0。最后解锁互斥锁,并返回读取的数据。
在主函数中,首先初始化缓冲区,然后创建生产者线程和消费者线程,并通过pthread_join函数等待线程结束。
相关问题
void init(struct prodcons * b) { pthread_mutex_init(&b->lock, NULL); pthread_cond_init(&b->notempty, NULL); pthread_cond_init(&b->notfull, NULL); b->readpos = 0; b->writepos = 0; }
这段代码实现了一个初始化函数 init(),其作用是初始化一个生产者-消费者模型的缓冲区。函数接收一个指向 struct prodcons 的指针 b,其中包括互斥锁 lock、条件变量 notempty 和 notfull,以及读写指针 readpos 和 writepos。具体实现中,使用 pthread_mutex_init() 函数初始化互斥锁 lock,使用 pthread_cond_init() 函数初始化条件变量 notempty 和 notfull,这些函数都会分别为相应的变量分配内存并进行初始化。最后,将读写指针 readpos 和 writepos 的初始值设置为 0。这个初始化函数是保证缓冲区的正确性和线程安全性的基础。
注释下段代码void init(struct prodcons * b) { pthread_mutex_init(&b->lock, NULL); pthread_cond_init(&b->notempty, NULL); pthread_cond_init(&b->notfull, NULL); b->readpos = 0; b->writepos = 0; } /*--------------------------------------------------------*/ /* 向缓冲区中写入一个整数*/ void put(struct prodcons * b, int data) { pthread_mutex_lock(&b->lock); /*等待缓冲区非满*/ if (b->writepos == 0){ printf("第十七个数,wait for not full\n"); pthread_cond_signal(&b->notempty); pthread_cond_wait(&b->notfull,&b->lock); } /*写数据并且指针前移*/ b->buffer[b->writepos] = data; b->writepos++; if (b->writepos >= BUFFER_SIZE) b->writepos = 0; /*设置缓冲区非空信号*/ pthread_mutex_unlock(&b->lock); if (data == -1){ printf("最后,生产任务结束\n"); pthread_cond_signal(&b->notempty); } } /*--------------------------------------------------------*/ /*从缓冲区中读出一个整数 */ int get(struct prodcons * b) { int data; pthread_mutex_lock(&b->lock); /* 等待缓冲区非空*/ if (0 == b->readpos){ pthread_cond_signal(&b->notfull); pthread_cond_wait(&b->notempty,&b->lock); printf("wait for not empty\n"); } /* 读数据并且指针前移 */ data = b->buffer[b->readpos]; b->readpos++; if (b->readpos >= (BUFFER_SIZE)) b->readpos = 0; /* 设置缓冲区非满信号*/ pthread_mutex_unlock(&b->lock); return data; }
这段代码实现了一个生产者-消费者模型的缓冲区。其中,init() 函数用于初始化缓冲区,包括初始化互斥锁和条件变量,以及设置读写指针的初始值。put() 函数用于向缓冲区中写入一个整数,它首先获取互斥锁,然后判断缓冲区是否已满,如果已满则等待条件变量 notfull 的信号,直到被唤醒后再次检查缓冲区是否已满,否则写入数据并将写指针前移。最后释放互斥锁并发送 notempty 信号,以通知消费者缓冲区非空。get() 函数用于从缓冲区中读出一个整数,它首先获取互斥锁,然后判断缓冲区是否为空,如果为空则等待条件变量 notempty 的信号,直到被唤醒后再次检查缓冲区是否为空,否则读取数据并将读指针前移。最后释放互斥锁并发送 notfull 信号,以通知生产者缓冲区非满。需要注意的是,该缓冲区的实现是线程安全的,即多个线程可以同时读写缓冲区而不会出现数据竞争问题。
阅读全文