三个线程分别打印ABC,按顺序输出ABCABC...

#include #include #include #include #include #include using namespace std; pthread_mutex_t lockA; pthread_mutex_t lockB; pthread_mutex_t lockC; int i = 1; void* funA(void* args) { while(1) {pthread_mutex_lock(&lockB); pthread_mutex_lock(&lockC); printf("funA...A\n"); pthread_mutex_unlock(&lockB); sleep(1); pthread_mutex_unlock(&lockC); sleep(1); } return NULL; }void* funB(void* args) { while(1) {pthread_mutex_lock(&lockC); pthread_mutex_lock(&lockA); printf("funB...B\n"); pthread_mutex_unlock(&lockC); sleep(1); pthread_mutex_unlock(&lockA); sleep(1); } return NULL; }void* funC(void* args) { while(1) {pthread_mutex_lock(&lockB); pthread_mutex_lock(&lockA); printf("funC...C\n"); pthread_mutex_unlock(&lockA); sleep(1); pthread_mutex_unlock(&lockB); sleep(1); } return NULL; }int main(int argc,const char* argv[]) { pthread_t thd1; pthread_t thd2; pthread_t thd3; pthread_mutex_init(&lockA, NULL); pthread_mutex_init(&lockB, NULL); pthread_mutex_init(&lockC, NULL); pthread_create(&thd1, NULL, funA, NULL); pthread_create(&thd2, NULL, funB, NULL); pthread_create(&thd3, NULL, funC, NULL); pthread_join(thd1, NULL); pthread_join(thd2, NULL); pthread_join(thd3, NULL); pthread_mutex_destroy(&lockA); pthread_mutex_destroy(&lockB); pthread_mutex_destroy(&lockC); return 0; }

上面的程序容易造成死锁,例如 第一个线程 占有B,第二个线程占有C时
改进版

#include #include #include #include #include #include using namespace std; pthread_mutex_t lock; // pthread_mutex_t lockA; // pthread_mutex_t lockB; // pthread_mutex_t lockC; pthread_cond_t condA; pthread_cond_t condB; pthread_cond_t condC; int i = 1; void* funA(void* args) { while(1) {pthread_mutex_lock(&lock); while(1) {pthread_cond_wait(&condA, &lock); printf("funA...A\n"); } pthread_mutex_unlock(&lock); } return NULL; }void* funB(void* args) { while(1) {pthread_mutex_lock(&lock); while(1) {pthread_cond_wait(&condB, &lock); printf("funB...B\n"); }pthread_mutex_unlock(&lock); } return NULL; }void* funC(void* args) { while(1) { pthread_mutex_lock(&lock); while(1) { pthread_cond_wait(&condC, &lock); printf("funC...C\n"); } pthread_mutex_unlock(&lock); } return NULL; }int main(int argc,const char* argv[]) { pthread_t thd1; pthread_t thd2; pthread_t thd3; // pthread_mutex_init(&lockA, NULL); // pthread_mutex_init(&lockB, NULL); // pthread_mutex_init(&lockC, NULL); pthread_mutex_init(&lock, NULL); pthread_cond_init(&condA, NULL); pthread_cond_init(&condB, NULL); pthread_cond_init(&condC, NULL); pthread_create(&thd1, NULL, funA, NULL); pthread_create(&thd2, NULL, funB, NULL); pthread_create(&thd3, NULL, funC, NULL); while(1) { sleep(1); pthread_cond_signal(&condA); sleep(1); pthread_cond_signal(&condB); sleep(1); pthread_cond_signal(&condC); sleep(1); } pthread_join(thd1, NULL); pthread_join(thd2, NULL); pthread_join(thd3, NULL); // pthread_mutex_destroy(&lockA); // pthread_mutex_destroy(&lockB); // pthread_mutex_destroy(&lockC); pthread_mutex_destroy(&lock); pthread_cond_destroy(&condA); pthread_cond_destroy(&condB); pthread_cond_destroy(&condC); return 0; }

【三个线程分别打印ABC,按顺序输出ABCABC...】上面的版本忽略了线程之间的协作关系
改进版

#include #include #include #include #include #include using namespace std; //pthread_mutex_t lock; pthread_mutex_t lockA; pthread_mutex_t lockB; pthread_mutex_t lockC; pthread_cond_t condA; pthread_cond_t condB; pthread_cond_t condC; void* funA(void* args) { while(1) {pthread_mutex_lock(&lockB); while(1) { printf("funA...A\n"); pthread_cond_signal(&condB); pthread_cond_wait(&condA, &lockB); sleep(1); } pthread_mutex_unlock(&lockB); } return NULL; }void* funB(void* args) { while(1) {pthread_mutex_lock(&lockC); while(1) { printf("funB...B\n"); pthread_cond_signal(&condC); pthread_cond_wait(&condB, &lockC); sleep(1); }pthread_mutex_unlock(&lockC); } return NULL; }void* funC(void* args) { while(1) { pthread_mutex_lock(&lockA); while(1) { printf("funC...C\n"); pthread_cond_signal(&condA); pthread_cond_wait(&condC, &lockA); sleep(1); }pthread_mutex_unlock(&lockA); } return NULL; }int main(int argc,const char* argv[]) { pthread_t thd1; pthread_t thd2; pthread_t thd3; pthread_mutex_init(&lock, NULL); pthread_mutex_init(&lockA, NULL); pthread_mutex_init(&lockB, NULL); pthread_mutex_init(&lockC, NULL); pthread_cond_init(&condA, NULL); pthread_cond_init(&condB, NULL); pthread_cond_init(&condC, NULL); pthread_create(&thd1, NULL, funA, NULL); sleep(1); pthread_create(&thd2, NULL, funB, NULL); sleep(1); pthread_create(&thd3, NULL, funC, NULL); pthread_join(thd1, NULL); pthread_join(thd2, NULL); pthread_join(thd3, NULL); //pthread_mutex_destroy(&lock); pthread_mutex_destroy(&lockA); pthread_mutex_destroy(&lockB); pthread_mutex_destroy(&lockC); pthread_cond_destroy(&condA); pthread_cond_destroy(&condB); pthread_cond_destroy(&condC); return 0; }

上面这版本还是有死锁的风险
改进版 干脆就用一个锁

#include #include #include #include #include #include using namespace std; pthread_mutex_t lock; pthread_cond_t condA; pthread_cond_t condB; pthread_cond_t condC; void* funA(void* args) { while(1) {pthread_mutex_lock(&lock); while(1) { printf("funA...A\n"); pthread_cond_signal(&condB); pthread_cond_wait(&condA, &lock); //sleep(1); } pthread_mutex_unlock(&lockB); } return NULL; }void* funB(void* args) { while(1) {pthread_mutex_lock(&lock); while(1) { printf("funB...B\n"); pthread_cond_signal(&condC); pthread_cond_wait(&condB, &lock); //sleep(1); }pthread_mutex_unlock(&lock); } return NULL; }void* funC(void* args) { while(1) { pthread_mutex_lock(&lock); while(1) { printf("funC...C\n"); pthread_cond_signal(&condA); pthread_cond_wait(&condC, &lock); //sleep(1); }pthread_mutex_unlock(&lock); } return NULL; }int main(int argc,const char* argv[]) { pthread_t thd1; pthread_t thd2; pthread_t thd3; pthread_mutex_init(&lock, NULL); pthread_cond_init(&condA, NULL); pthread_cond_init(&condB, NULL); pthread_cond_init(&condC, NULL); pthread_create(&thd1, NULL, funA, NULL); sleep(1); pthread_create(&thd2, NULL, funB, NULL); sleep(1); pthread_create(&thd3, NULL, funC, NULL); pthread_join(thd1, NULL); pthread_join(thd2, NULL); pthread_join(thd3, NULL); pthread_mutex_destroy(&lock); pthread_cond_destroy(&condA); pthread_cond_destroy(&condB); pthread_cond_destroy(&condC); return 0; }

改进版 为了解放main对线程的调度,全面实现自动化

#include #include #include #include #include #include using namespace std; pthread_mutex_t lock; pthread_cond_t condA; pthread_cond_t condB; pthread_cond_t condC; int i = 1; void* funA(void* args) { while(1) {pthread_mutex_lock(&lock); if(i == 1) { while(1) { i = 2; printf("funA...A\n"); pthread_cond_signal(&condB); pthread_cond_wait(&condA, &lock); sleep(1); }} pthread_mutex_unlock(&lock); } return NULL; }void* funB(void* args) { while(1) {pthread_mutex_lock(&lock); if(i == 2) { while(1) { i = 3; printf("funB...B\n"); pthread_cond_signal(&condC); pthread_cond_wait(&condB, &lock); sleep(1); } } pthread_mutex_unlock(&lock); } return NULL; }void* funC(void* args) { while(1) { pthread_mutex_lock(&lock); if(i == 3) { while(1) { printf("funC...C\n"); pthread_cond_signal(&condA); pthread_cond_wait(&condC, &lock); sleep(1); } } pthread_mutex_unlock(&lock); } return NULL; }int main(int argc,const char* argv[]) { pthread_t thd1; pthread_t thd2; pthread_t thd3; pthread_mutex_init(&lock, NULL); pthread_cond_init(&condA, NULL); pthread_cond_init(&condB, NULL); pthread_cond_init(&condC, NULL); pthread_create(&thd1, NULL, funA, NULL); //sleep(1); pthread_create(&thd2, NULL, funB, NULL); pthread_create(&thd3, NULL, funC, NULL); pthread_join(thd1, NULL); pthread_join(thd2, NULL); pthread_join(thd3, NULL); pthread_mutex_destroy(&lock); pthread_cond_destroy(&condA); pthread_cond_destroy(&condB); pthread_cond_destroy(&condC); return 0; }

最终正确版,上面的代码说明自己并没有理解wait,和signal的作用

#include #include #include #include #include #include using namespace std; pthread_mutex_t lock; pthread_cond_t condA; pthread_cond_t condB; pthread_cond_t condC; int i = 1; void* funA(void* args) { while(1) {pthread_mutex_lock(&lock); while(i != 1) {pthread_cond_wait(&condA, &lock); //wait是做完事情之前等待,是用来等待某一条件}i = 2; printf("funA...A\n"); pthread_cond_signal(&condB); //通知下一个线程 pthread_mutex_unlock(&lock); } return NULL; }void* funB(void* args) { while(1) {pthread_mutex_lock(&lock); while(i != 2) {pthread_cond_wait(&condB, &lock); sleep(1); } i = 3; printf("funB...B\n"); pthread_cond_signal(&condC); pthread_mutex_unlock(&lock); } return NULL; }void* funC(void* args) { while(1) { pthread_mutex_lock(&lock); while(i != 3) {pthread_cond_wait(&condC, &lock); //sleep(1); } i = 1; printf("funC...C\n"); pthread_cond_signal(&condA); pthread_mutex_unlock(&lock); } return NULL; }int main(int argc,const char* argv[]) { pthread_t thd1; pthread_t thd2; pthread_t thd3; pthread_mutex_init(&lock, NULL); pthread_cond_init(&condA, NULL); pthread_cond_init(&condB, NULL); pthread_cond_init(&condC, NULL); pthread_create(&thd1, NULL, funA, NULL); //sleep(1); pthread_create(&thd2, NULL, funB, NULL); pthread_create(&thd3, NULL, funC, NULL); pthread_join(thd1, NULL); pthread_join(thd2, NULL); pthread_join(thd3, NULL); pthread_mutex_destroy(&lock); pthread_cond_destroy(&condA); pthread_cond_destroy(&condB); pthread_cond_destroy(&condC); return 0; }


一个互斥量和一个条件变量也可以实现这个例子,但是这种做法会造成线程忙等,我们的最终版就没这个毛病











    推荐阅读