- 论坛徽章:
- 0
|
本帖最后由 vesontio 于 2014-12-19 20:12 编辑
在写一个练习,就是最典型的“生产者”(Producer)和“消费者”(Consumer)的问题,两者各用一种线程来代表,各个线程共享一个int类型的数值val。
Producer尝试将val置1,如果发现val已经为1,则wait;
Consumer则尝试将val置0,如果发现val已经为0,则wait;
任意一个线程修改val的值之后,就会呼叫pthread_cond_signal,知会其他线程。
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <pthread.h>
- #define TH_POOL_SZ 10
- #define TH_NB_LOOP 100
- static pthread_mutex_t th_lock = PTHREAD_MUTEX_INITIALIZER;
- static pthread_cond_t th_cond = PTHREAD_COND_INITIALIZER;
- typedef struct th_data {
- int val;
- } th_data_t;
复制代码 程序头就是如此,一个pthread_mutex_t,一个pthread_cond_t,下面的结构体是传递给线程的参数。程序会一共创建TH_POOL_SZ个“生产者”和“消费者”,每个线程尝试循环TH_NB_LOOP次,每次都试着改变val的值。
- static void *cons_runnable(void *arg) {
- int i;
- for (i = 0; i < TH_NB_LOOP; i ++) {
- if (pthread_mutex_lock(&th_lock) != 0) {
- perror("Failed to lock mutex");
- pthread_exit(NULL);
- }
- printf("Consumer locked.\n");
- th_data_t *data = (th_data_t *)arg;
- while (data->val == 0) {
- printf("Value null, consumer is waiting ...\n");
- if (pthread_cond_wait(&th_cond, &th_lock) != 0) {
- perror("Failed to wait on mutex");
- pthread_exit(NULL);
- }
- }
- printf("Consumer waked up.\n");
- data->val --;
- printf("Value decremented.\n");
- if (pthread_mutex_unlock(&th_lock) != 0) {
- perror("Failed to unlock mutex");
- pthread_exit(NULL);
- }
- printf("Consumer unlocked.\n");
- if (pthread_cond_signal(&th_cond) != 0) {
- perror("Failed to signal other threads");
- pthread_exit(NULL);
- }
- printf("Consumer signaled other threads\n");
- }
- printf("Consumer terminated.\n");
- pthread_exit(NULL);
- }
复制代码 “消费者”(Consumer)的代码,没什么特别的,先加锁,发现val为0就wait,被**后就更新val的值,更新完解锁,并知会其他线程。
- static void *prod_runnable(void *arg) {
- int i;
- for (i = 0; i < TH_NB_LOOP; i ++) {
- if (pthread_mutex_lock(&th_lock) != 0) {
- perror("Failed to lock mutex");
- pthread_exit(NULL);
- }
- printf("Producer locked.\n");
- th_data_t *data = (th_data_t *)arg;
- while (data->val == 1) {
- printf("Value set, producer is waiting ...\n");
- if (pthread_cond_wait(&th_cond, &th_lock) != 0) {
- perror("Failed to wait on mutex");
- pthread_exit(NULL);
- }
- }
- printf("Producer waked up.\n");
- data->val ++;
- printf("Value incremented.\n");
- if (pthread_mutex_unlock(&th_lock) != 0) {
- perror("Failed to unlock mutex");
- pthread_exit(NULL);
- }
- printf("Producer unlocked.\n");
- if (pthread_cond_signal(&th_cond) != 0) {
- perror("Failed to signal other threads");
- pthread_exit(NULL);
- }
- printf("Producer signaled other threads.\n");
- }
- printf("Producer terminated.\n");
- pthread_exit(NULL);
- }
复制代码 “生产者”(Producer)的代码基本就是和“消费者”(Consumer)反过来。- int main (void) {
- int i;
- th_data_t data;
- pthread_t th_pool_cons[TH_POOL_SZ];
- pthread_t th_pool_prod[TH_POOL_SZ];
- data.val = 0;
- for (i = 0; i < TH_POOL_SZ; i ++) {
- if (pthread_create(&th_pool_cons[i], NULL, cons_runnable, &data) != 0) {
- perror("Failed to create consumer thread");
- return -1;
- }
- if (pthread_create(&th_pool_prod[i], NULL, prod_runnable, &data) != 0) {
- perror("Failed to create producer thread");
- return -1;
- }
- }
- printf("%d threads created.\n", TH_POOL_SZ * 2);
- for (i = 0; i < TH_POOL_SZ; i ++) {
- if (pthread_join(th_pool_cons[i], NULL) != 0) {
- perror("Failed to join consumer thread");
- return -1;
- }
- }
- for (i = 0; i < TH_POOL_SZ; i ++) {
- if (pthread_join(th_pool_prod[i], NULL) != 0) {
- perror("Failed to join producer thread");
- return -1;
- }
- }
- printf("%d threads joined.\n", TH_POOL_SZ * 2);
- printf("Final value of data: %d.\n", data.val);
- printf("Fin.\n");
- return 0;
- }
复制代码 main函数的话基本就是创建几个线程,然后等着join他们。最后的结果出来,理论上val等于0。但是每次都是在某个“消费者”(Consumer)等待的时候就卡死不动了。
前前后后看了几遍也不知道问题出在神马地方。
希望各路大神们帮帮看看,谢谢! |
|