linux线程通信和同步(信号量)

一、信号量和条件变量的异同

  • 信号量和条件变量都可以允许多个线程以无竞争的方式等待特定条件或信号的产生;
  • 信号量在使用时会设置一个初始值,每次只能唤醒一个正在等待信号的线程,而条件变量则没有初始值,并且可以一次性唤醒所有等待条件变量的线程;
  • 条件变量一般和互斥锁一起使用,这一点比信号量稍微麻烦一些;

二、信号量使用注意事项

  • 如果信号量的初始值不为0,那么即使不调用sem_post,使用sem_wait的线程依然可以被唤醒,直到信号量的值为0;
  • 每一次调用sem_post,信号量的值都会被加一,每一次调用sem_wait解除线程的阻塞,信号量的值都会被减一。

二、常用函数

头文件:#include <semaphore.h>

1.sem_init

函数原型:int sem_init(sem_t *sem, int pshared, unsigned int value);
函数功能:初始化一个信号量,并设置信号量的初始值为value,每次调用sem_post信号量的值会加一
函数参数:sem 信号量句柄
          shared 0表示信号量只能在线程间使用,非0值表示可以在进程间使用
          value 初始值
返回值:成功返回0,失败返回对应的错误码

2.sem_post

函数原型:int sem_post(sem_t *sem);
函数功能:调用该函数可以唤醒使用sem_wait函数等待信号量的线程,同时sem指向的信号值会加一。
函数参数:sem 信号量句柄
返回值:成功返回0,失败返回对应的错误码

3.sem_wait

函数原型:int sem_wait(sem_t *sem);
函数功能:阻塞等待信号量的到来,同时sem指向的信号值会减一。

4.sem_trywait

函数原型:int sem_wait(sem_t *sem);
函数功能:非阻塞等待信号量的到来,如果信号量的值为0,返回对应的错误码

5.sem_timedwait

函数原型: int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
函数功能:阻塞等待信号量的到来,并设置超时时间

6.sem_timedwait

函数原型: int sem_getvalue(sem_t *sem);
函数功能:获取信号量的当前值

7.sem_destroy

函数原型: int sem_destroy(sem_t *sem); 
函数功能:销毁信号量

8.sem_getvalue

函数原型:  int sem_getvalue(sem_t *sem, int *sval);
函数功能:获取信号量的当前值

示例:

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
sem_t g_sem;

void *pthread1(void *param)
{
	int value;
	while(1)
	{
		sem_post(&g_sem);
		sem_getvalue(&g_sem,&value);
		printf("sem post,signal num:%d\r\n",value);
		sleep(1);
	}
}
void *pthread2(void *param)
{
	int ret = -1;
	int value;
    while(1)
	{
		ret = sem_wait(&g_sem);
		if(0 == ret)
		{
			sem_getvalue(&g_sem,&value);
			printf("sem wait,signal num:%d\r\n",value);
		}
		
	}		
}
int main()
{
	int ret = -1;
	pthread_t tid1,tid2;
	
	ret = sem_init(&g_sem,0,5);
	if(0!=ret)
	{
		printf("sem init error\r\n");
	}
	pthread_create(&tid1,NULL,pthread1,NULL);
	pthread_create(&tid2,NULL,pthread2,NULL);
	pthread_join(tid1,NULL);
	pthread_join(tid2,NULL);
    return 0;
}

运行结果:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X9C32f9F-1595729944368)(2F6352567AA34A3A8AE019D1ADDD67FF)]
如果长时间运行会出现num都为0的情况,这是因为sem_post之后,获取到的value值已经被sem_wait修改。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值