多線程之信號量

本文的信號量類型爲POSIX無名信號量

1、信號量基礎知識

  我們通常寫程序時會定義的一個變量flag,然後用if判斷,當flag爲1時執行,flag爲0時不執行某段程序,而信號量sem就像一個flag一樣,只不過是在線程中使用,通過信號量我們可以控制多個線程的執行順序。

2、信號量的主要用到的函數

int sem_init(sem_t *sem, int pshared, unsigned int value);
int sem_destroy(sem_t *sem);
int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
int sem_post(sem_t *sem);

 

sem_init():初始化信號量,其中sem是要初始化的信號量,信號量變量用sem_t 定義,例:sem_t A,B,C;定義信號量A,B,C,pshared表示此信號量是在進程間共享還是線程間共享,由於目前 Linux 還沒有實現進程間共享信號量,所以這個值只能夠取 0,就表示這個信號量是當前進程的局部信號量,value是信號量的初始值,也就相當於flag的初始值。成功返回0,失敗返回-1。

sem_wait()函數是等待(獲取)信號量,如果信號量的值大於0,將信號量的值減1,立即返回。如果信號量的值爲0,則進程/線程阻塞。成功返回0,失敗返回-1。

sem_trywait()函數也是等待信號量,如果指定信號量的計數器爲0,那麼直接返回EAGAIN錯誤,而不是阻塞等待。

sem_post()函數是釋放信號量,讓信號量的值加1。成功返回0,失敗返回-1。

sem_destroy():銷燬信號量,其中sem是要銷燬的信號量。只有用sem_init初始化的信號量才能用sem_destroy()函數銷燬。成功返回0,失敗返回-1。

3、使用信號量實現循環打印n個ABC

#include<bits/stdc++.h>
#include<semaphore.h>
using namespace std;
sem_t  semA,semB,semC;
pthread_t  pa,pb,pc;

void* printA(void* arg)
{
    int n = (unsigned long long)arg;
    for(int i=1;i<=n;i++)
    {
         sem_wait(&semA);
         cout<<"A";
         sem_post(&semB);
    }
    pthread_exit(NULL);//退出線程
    
}

void* printB(void* arg)
{
    int n = (unsigned long long)arg;
    for(int i=1;i<=n;i++)
    {
        sem_wait(&semB);
         cout<<"B";
        sem_post(&semC);
    }
    pthread_exit(NULL);//退出線程
    
}

void* printC(void* arg)
{
    int n = (unsigned long long)arg;
    for(int i=1;i<=n;i++)
    {
       sem_wait(&semC);
       cout<<"C";
       sem_post(&semA);
    }
     pthread_exit(NULL);//退出線程
}
int main()
{
    int n;
    while(cin>>n)
    {
        sem_init(&semA,0,1);
        sem_init(&semB,0,0);
        sem_init(&semC,0,0);
        pthread_create(&pa,NULL,printA,(void*)(unsigned long long)(n));
        pthread_create(&pb,NULL,printB,(void*)(unsigned long long)(n));
        pthread_create(&pc,NULL,printC,(void*)(unsigned long long)(n));

        void * thread_ret;
        pthread_join(pa,&thread_ret);
        pthread_join(pb,&thread_ret);
        pthread_join(pc,&thread_ret);

        sem_destroy(&semA);
        sem_destroy(&semB);
        sem_destroy(&semC);

    }

}

代碼的運行環境是linux,在終端使用g++ name.cpp -o test -lpthread  -static

使用函數pthread_create創建線程,給線程函數傳遞參數n

使用函數pthread_join回收線程

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