利用條件變量實現進程間同步示例講解


利用共享內存存放條件變量和鎖來達到同步的目的。

[1] get_cond_wait.c 初始化條件變量和鎖函數

#include "public.h"

char* get_cond_wait(const char* filename, pthread_cond_t** outCond, pthread_mutex_t** outMutex)
{
    pthread_cond_t* cond;
    pthread_mutex_t* mutex;
    char* g_share_mem;

    int fd = shm_open(filename, O_RDWR|O_CREAT|O_EXCL, 0777);
    if(fd > 0)
    {
        // create ok,設置共享內存長度
        ftruncate(fd, 4096);
        g_share_mem = (char*)mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
        cond = (pthread_cond_t*)g_share_mem;
        mutex = (pthread_mutex_t*)(g_share_mem + sizeof(pthread_cond_t));

        // 初始化一個進程間通信的鎖和等待變量
        pthread_condattr_t cond_attr;
        pthread_condattr_init(&cond_attr);
        pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED);
        pthread_cond_init(cond, &cond_attr);


        // 初始化一個可以在進程間使用的鎖
        pthread_mutexattr_t mutex_attr;
        pthread_mutexattr_init(&mutex_attr);
        pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED);
        pthread_mutex_init(mutex, &mutex_attr);
    }
    else
    {
        fd = shm_open(filename, O_RDWR, 0777);
        // 其他進程已經初始化過了,這裏不要再初始化
        g_share_mem = (char*)mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
        cond = (pthread_cond_t*)g_share_mem;
        mutex = (pthread_mutex_t*)(g_share_mem + sizeof(pthread_cond_t));
    }
    // 所有對該文件的映射都unmap之後,該文件會真正的刪除,
    // 保證該文件在所有通信的進程退出後,會被刪除
    close(fd);
//    shm_unlink("/test_share_mem"); 

    *outCond = cond;
    *outMutex = mutex;

    return g_share_mem;
}

[2] cond_signal.c 發送信號函數

#include "public.h"

pthread_cond_t* cond;
pthread_mutex_t* mutex;
char* g_share_mem;

extern char* get_cond_wait(const char* filename, pthread_cond_t** outCond, pthread_mutex_t** outMutex);

int main()
{
    g_share_mem = get_cond_wait("/test_share_mem", &cond, &mutex);
    
    while(1)
    {
        char buf[1024];
        fgets(buf, sizeof(buf), stdin);

        pthread_cond_signal(cond);
    }
}

[3] cond_wait.c 等待信號函數

#include "public.h"

pthread_cond_t* cond;
pthread_mutex_t* mutex;

char* g_share_mem;

extern char* get_cond_wait(const char* filename, pthread_cond_t** outCond, pthread_mutex_t** outMutex);

int main()
{
    g_share_mem = get_cond_wait("/test_share_mem", &cond, &mutex);

    while(1)
    {
        pthread_mutex_lock(mutex);  
        pthread_cond_wait(cond, mutex);  
        pthread_mutex_unlock(mutex);

        printf("wait ok\n");
    }
}

[4] Makefile

all: cond_wait cond_signal

cond_wait: cond_wait.c get_cond_wait.c
	gcc -o cond_wait cond_wait.c get_cond_wait.c  -lpthread -lrt

cond_signal: cond_signal.c get_cond_wait.c
	gcc -o cond_signal cond_signal.c get_cond_wait.c -lpthread -lrt

[4] 運行結果

./cond_signal
hahah

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