(1)三个线程协作打印ABCABCABC
(2)两个线程协作打印奇数偶数
--------------------------------
(1)三个线程协作打印ABCABCABC
(1.1)思路
并发编程核心是三大块:分工、互斥和同步。
1)互斥
这道题并不涉及共享变量,所以不需要考虑互斥,首先排除。
2)同步
一眼就能看出这道题考的就是同步,那怎么同步呢?很容易想到的方法,就是每个线程打印前,等待别的线程通知;打印后,再去通知别的线程。
 等待与唤醒,无非就是Object的wait、notify;
3)分工
就是考虑每个线程要做什么事情,需要哪些成员变量
每个线程需要两个Condition变量,一个condition用来等待上个线程通知,一个condition用来通知下个线程。
每个线程需要打印自己的字母,然后更改字母,通知下一个线程进行打印;
分析:
在生产者消费者中,生产者有2个条件变量,消费者两个条件变量,2个角色,一个两个条件变量即可;
在此中,printA、printB,printC线程各2个条件变量,3个角色,需要3个条件变量;
条件变量 + 线程互斥量来进行线程的同步,整体只需一个线程互斥量。
另外:线程互斥量也可以包含临界资源,此中的临界资源就是要打印的变量,因为线程中要修改该变量。
(1.2)分析
条件变量一般和线程互斥量共同作用来控制线程之间的协作;
pthread_cond_t类型;
pthread_cond_wait()函数;
pthread_cond_signal()函数;
pthread_mutex_t类型;
pthread_mutex_lock()函数;
pthread_mutex_unlock()函数;
(1.3)代码实现
#include <iostream>
 #include <cstdlib>
 #include <pthread.h>
 #include <unistd.h>
 using namespace std;
 #define NUM_THREADS     3
  
 pthread_cond_t Aready = PTHREAD_COND_INITIALIZER;
 pthread_cond_t Bready = PTHREAD_COND_INITIALIZER;
 pthread_cond_t Cready = PTHREAD_COND_INITIALIZER;
 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 string nextchar = "A";   //初始化=A,保证先打印A;即printA线程先启动;
//线程A
 void* printerA(void*)
 {
     for (int i = 0; i < 10; i++) {
         pthread_mutex_lock(&mutex);
         while (nextchar != "A") {
             pthread_cond_wait(&Aready, &mutex);
         }
         cout << nextchar;
         nextchar = "B";
         pthread_mutex_unlock(&mutex);
         pthread_cond_signal(&Bready);
     }
     pthread_exit((void*) 1);
 }
  
//线程B
 void* printerB(void*)
 {
     for(int i = 0; i < 10; i++) {
         pthread_mutex_lock(&mutex);
         while (nextchar != "B") {
             pthread_cond_wait(&Bready, &mutex);
         }
         cout << nextchar;
         nextchar = "C";
         pthread_mutex_unlock(&mutex);
         pthread_cond_signal(&Cready);
     }
     pthread_exit((void*) 2);
 }
  
  //线程C
 void* printerC(void*)
 {
     for (int i = 0; i < 10; i++) {
         pthread_mutex_lock(&mutex);
         while (nextchar != "C") {
             pthread_cond_wait(&Cready, &mutex);
         }
         cout << nextchar;
         nextchar = "A";
         pthread_mutex_unlock(&mutex);
         pthread_cond_signal(&Aready);
     }
     pthread_exit((void*) 1);
 }
  
  
 int main ()
 {
    int rc;
    int i;
    pthread_t threads[NUM_THREADS];
    pthread_attr_t attr;
    void *status;
  
    // 初始化并设置线程为可连接的(joinable)
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
    pthread_create(&threads[0], NULL, printerA, NULL);
    pthread_create(&threads[1], NULL, printerB, NULL);
    pthread_create(&threads[2], NULL, printerC, NULL);
  
    // 删除属性,并等待其他线程
    pthread_attr_destroy(&attr);
    for( i=0; i < NUM_THREADS; i++ ){
       rc = pthread_join(threads[i], &status);
       if (rc){
          cout << "Error:unable to join," << rc << endl;
          exit(-1);
       }
       cout << "Main: completed thread id :" << i ;
       cout << "  exiting with status :" << status << endl;
    }
  
    cout << "Main: program exiting." << endl;
    pthread_exit(NULL);
 }
------
(2)两个线程协作打印奇数偶数
#include <iostream>
 #include <cstdlib>
 #include <pthread.h>
 #include <unistd.h>
  
 using namespace std;
 #define NUM_THREADS     2
  
 pthread_cond_t Oddready = PTHREAD_COND_INITIALIZER;  // 奇数ready
 pthread_cond_t UnOddready = PTHREAD_COND_INITIALIZER;  // 偶数ready
 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 int i = 0;   //起始为偶数,说明先打印偶数,先启动偶数线程;
  /*
* 此中一个线程打印奇数,一个线程打印偶数,只有2个角色,就只有2个条件变量即可。
*/
 // 打印奇数
 void* printerOdd(void*)
 {
     for (int index = 0; index < 10; index++) {
         pthread_mutex_lock(&mutex);
         while (i % 2 == 0) { //不是奇数,则等待;
             pthread_cond_wait(&Oddready, &mutex);  // 当前是偶数的话,等待奇数ready条件满足
         }
         cout << "printOdd " << i << " ";
         i++;
         pthread_mutex_unlock(&mutex);
         pthread_cond_signal(&UnOddready);
     }
     pthread_exit((void*) 1);
 }
  
 void* printerUnOdd(void*)
 {
     for(int index = 0; index < 10; index++) {
         pthread_mutex_lock(&mutex);
         while (i % 2 != 0) {
             pthread_cond_wait(&UnOddready, &mutex); // 当前是奇数,等待偶数ready条件满足
         }
         cout << "printUnodd " << i << " ";
         i++;
         pthread_mutex_unlock(&mutex);
         pthread_cond_signal(&Oddready);  // 打印完偶数后,将条件变量“奇数ready” 置为true
     }
     pthread_exit((void*) 2);
 }
  
 int main ()
 {
    int rc;
    int i;
    pthread_t threads[NUM_THREADS];
    pthread_attr_t attr;
    void *status;
  
  
    // 初始化并设置线程为可连接的(joinable)
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
  
    pthread_create(&threads[0], NULL, printerOdd, NULL);
    pthread_create(&threads[1], NULL, printerUnOdd, NULL);
  
    // 删除属性,并等待其他线程
    pthread_attr_destroy(&attr);
    for( i=0; i < NUM_THREADS; i++ ){
       rc = pthread_join(threads[i], &status);
       if (rc){
          cout << "Error:unable to join," << rc << endl;
          exit(-1);
       }
       cout << endl;
       cout << "Main: completed thread id :" << i ;
       cout << "  exiting with status :" << status << endl;
    }
  
    cout << "Main: program exiting." << endl;
    pthread_exit(NULL);
 }










