#if 0 linux实现生产者消费者模型 1. 防止虚假唤醒 2. 唤醒线程的时机很重要,否则会导致线程多次访问锁,影响性能 #endif #include#include #include #include using namespace std; int g_value = 0; pthread_mutex_t mutex = pthread_mutex_initializer; pthread_cond_t cond = pthread_cond_initializer; void* consumer1(void* arg) { printf("consumer[%d] begin consume.\n", (int)(*((int*)(arg)))); pthread_mutex_lock(&mutex); printf("consumer[%d] pthread_mutex_lock.\n", (int)(*((int*)(arg)))); while (g_value <= 0) {//防止虚假唤醒 printf("consumer[%d] begin wait.\n", (int)(*((int*)(arg)))); int ret = pthread_cond_wait(&cond, &mutex); if (ret) { printf("pthread_cond_wait error ret[%d].\n", ret); return null; } printf("consumer[%d] end wait.\n", (int)(*((int*)(arg)))); } --g_value; printf("consumer[%d] g_value:[%d].\n", (int)(*((int*)(arg))), g_value); pthread_mutex_unlock(&mutex); printf("consumer[%d] pthread_mutex_unlock.\n", (int)(*((int*)(arg)))); return null; } void* consumer2(void* arg) { printf("consumer[%d] begin consume.\n", (int)(*((int*)(arg)))); pthread_mutex_lock(&mutex); printf("consumer[%d] pthread_mutex_lock.\n", (int)(*((int*)(arg)))); while (g_value <= 0) {//防止虚假唤醒 printf("consumer[%d] begin wait.\n", (int)(*((int*)(arg)))); int ret = pthread_cond_wait(&cond, &mutex); if (ret) { printf("pthread_cond_wait error ret[%d].\n", ret); return null; } printf("consumer[%d] end wait.\n", (int)(*((int*)(arg)))); } --g_value; printf("consumer[%d] g_value:[%d].\n", (int)(*((int*)(arg))), g_value); pthread_mutex_unlock(&mutex); printf("consumer[%d] pthread_mutex_unlock.\n", (int)(*((int*)(arg)))); return null; } void* producer(void* arg) { cout << "producer begin product." << endl; pthread_mutex_lock(&mutex); printf("producer pthread_mutex_lock.\n"); g_value; cout << "producer g_value: " << g_value << endl; if (g_value > 0) { cout << "producer begin pthread_cond_broadcast." << endl; int ret = pthread_cond_broadcast(&cond); if (ret) { printf("pthread_cond_broadcast error ret[%d].\n", ret); return null; } cout << "producer end pthread_cond_broadcast." << endl; } printf("producer begin pthread_mutex_unlock.\n"); int ret = pthread_mutex_unlock(&mutex); if (ret) { printf("pthread_mutex_unlock error ret[%d].\n", ret); return null; } printf("producer end pthread_mutex_unlock.\n"); return null; } int join(pthread_t tid, void **retval) { int ret = pthread_join(tid, retval); if (ret) { return ret; } else { return 0; } } int main() { pthread_t tid_consumer[2] = {0}; pthread_t tid_producer = 0; int ret = -1; int _consumer1 = 1; ret = pthread_create(&tid_consumer[0], null, &consumer1, (void*)(&_consumer1)); if (ret) { printf("pthread_create error ret[%d].\n", ret); return -1; } sleep(1); int _consumer2 = 2; ret = pthread_create(&tid_consumer[1], null, &consumer2, (void*)(&_consumer2)); if (ret) { printf("pthread_create error ret[%d].\n", ret); return -1; } sleep(5); ret = pthread_create(&tid_producer, null, &producer, null); if (ret) { printf("pthread_create error ret[%d].\n", ret); return -1; } sleep(2); for (int i = 0; i < sizeof(tid_consumer)/sizeof(tid_consumer[0]); i) { ret = join(tid_consumer[i], null); if (ret) { printf("join error ret[%d].\n", ret); } } ret = join(tid_producer, null); if (ret) { printf("join error ret[%d].\n", ret); return -1; } printf("pthread join success.\n"); return 0; }