POSIX信号量实现互斥

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shanghairuoxiao/article/details/76650792

采用POSIX信号量实现互斥原语,实现线程间同步

/*
 * 采用信号量实现互斥原语
 */

#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
#include <sys/types.h>
#include <fcntl.h>
#include <pthread.h>

#define MAXNUM 10000

//用一个结构体封装命名信号量
struct slock
{
    sem_t* pSem;
    char name[_POSIX_NAME_MAX];
};

//为信号量结构体分配内存
struct slock* s_alloc()
{
    struct slock* sp;
    static int cnt;

    if((sp = (struct slock*)malloc(sizeof(struct slock))) == NULL)
        return NULL;

    do
    {
        snprintf(sp->name, sizeof(sp->name), "/%ld.%d", (long)getpid(), cnt++);
        sp->pSem = sem_open(sp->name, O_CREAT|O_EXCL, S_IRWXU, 1);
    }
    while((sp->pSem == SEM_FAILED) && (errno == EEXIST));

    if(sp->pSem == SEM_FAILED)
    {
        free(sp);
        return NULL;
    }
    sem_unlink(sp->name);
    return sp;
}

//释放内存
void s_free(struct slock* sp)
{
    if(sp != NULL)
    {
        sem_close(sp->pSem);
        free(sp);
        sp = NULL;
    }
}

//互斥lock
int s_lock(struct slock* sp)
{
    return sem_wait(sp->pSem);
}

//互斥unlock
int s_unlock(struct slock* sp)
{
    return sem_post(sp->pSem);
}

//互斥trylock
int s_trylock(struct slock* sp)
{
    return sem_trywait(sp->pSem);
}


//线程函数
static void* th_fun1(void* pArg);
static void* th_fun2(void* pArg);

//封装结构体作为参数传给线程
struct foo
{
    int count;
    struct slock* pslock;
};

int main()
{
    int err;
    pthread_t tid1, tid2;
    struct foo obj;

    obj.count = 0;
    if((obj.pslock = s_alloc()) == NULL)
        return 0;


    //创建线程
    err = pthread_create(&tid1, NULL, th_fun1, (void*)&obj);
    if(err != 0)
    {
        perror("pthread_create error");
        exit(1);
    }

    err = pthread_create(&tid2, NULL, th_fun2, (void*)&obj);
    if(err != 0)
    {
        perror("pthread_create error");
        exit(1);
    }

    //在主线程中等待线程退出
    pthread_join(tid1, NULL);
    printf("thread 1 exit\n");
    pthread_join(tid2, NULL);
    printf("thread 2 exit\n");

    s_free(obj.pslock);
    exit(0);
}


static void* th_fun1(void* pArg)
{
    while(1)
    {
        struct foo* pObj = (struct foo*)pArg;
        s_lock(pObj->pslock);
        if(pObj->count == MAXNUM)
        {
            s_unlock(pObj->pslock);
            break;
        }
        pObj->count++;
        printf("thread 1 print count: %d\n", pObj->count);
        s_unlock(pObj->pslock);
    }
    return ((void*)1);
}

static void* th_fun2(void* pArg)
{
    while(1)
    {
        struct foo* pObj = (struct foo*)pArg;
        s_lock(pObj->pslock);
        if(pObj->count == MAXNUM)
        {
            s_unlock(pObj->pslock);
            break;
        }
        pObj->count++;
        printf("thread 2 print count: %d\n", pObj->count);
        s_unlock(pObj->pslock);
    }
    return ((void*)2);
}

参考:APUE第三版第15章

猜你喜欢

转载自blog.csdn.net/shanghairuoxiao/article/details/76650792