linux多線程協作--legend050709

(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);
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章