利用条件变量实现进程间同步示例讲解


利用共享内存存放条件变量和锁来达到同步的目的。

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