版权声明:本文为博主原创文章,未经博主允许不得转载。 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章