线程之间利用信号量协调对共享资源访问的c++代码实现

本文介绍了线程间信号量的使用方法,包括信号量的初始化、增减操作及销毁等核心函数。通过一个具体的多线程交替打印字符的实例,展示了如何利用信号量实现线程间的同步。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先要了解线程之间的信号量的系统函数

信号量的类型为sem_t

#include<semaphore.h>
int sem_init (sem_t *sem, int pshared, unsigned int value);
这个函数的作用是对由sem指定的信号量进行初始化,设置好它的共享选项,并指定一个整数类型的初始值。

sem为指向信号量结构的一个指针
pshared参数控制着信号量的类型。如果 pshared的值是0,就表示它是当前进程的局部信号量;否则,其它进程就能够共享这个信号量,一般为0。

value给出了信号量的初始值

int sem_wait(sem_t * sem);
对应p操作

int sem_post(sem_t * sem);
对应v操作

关于信号量pv操作可以看信号量集知识整理

int sem_getvalue(sem_t *sem, int *valp);
获得信号量sem的值,并保存到valp中

int sem_destroy (sem_t *sem);
清理信号量的时候如果还有线程在等待它,用户就会收到一个错误。
然而在linux的线程中,其实是没有任何资源关联到信号量对象需要释放的,因此在linux中,销毁信号量对象的作用仅仅是测试是否有线程因为该信号量在等待。如果函数返回0说明没有,正常注销信号量,如果返回EBUSY,说明还有线程正在等待该信号量的信号。

信号量的使用如下步骤小结
1.声明信号量sem_t sem1;
2.初始化信号量sem_init(&sem1,0,1);
3.sem_post和sem_wait函数配合使用来达到线程同步
4.释放信号量int sem_destroy (sem_t *sem1);

 

下面是实现多线程之间交替打印成对字符的例子

#include<stdio.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include<semaphore.h>
sem_t resource;//定义信号量
void* f1(void* arg)
{
	int i = 0;
	char c = ((char*)arg)[0];
	for(;i<10;i++)
	{
		sem_wait(&resource);//p操作		
		printf("%c",c);
		fflush(stdout);
		sleep(rand()%3);
		printf("%c",c);
		fflush(stdout);
		sem_post(&resource);//v操作
		sleep(rand() % 2);
	}	
}

int main()
{
	pthread_t t1,t2,t3;
	sem_init(&resource,0,1);//初始化信号量
	pthread_create(&t1,NULL,f1,const_cast<char*>("0"));//创建3个线程,并传参要打印的字符,const_cast把const char*转换为char*
	pthread_create(&t2,NULL,f1,const_cast<char*>("x"));
	pthread_create(&t3,NULL,f1,const_cast<char*>("#"));
	pthread_join(t1,NULL);//确保3个线程都执行完毕
	pthread_join(t2,NULL);
	pthread_join(t3,NULL);
	sem_destroy(&resource);//销毁信号量
	return 0;
}


g++ test2.cpp -g -o test2.exe -lpthread

<93 mdsp209 [mct] :/home/mdcc/mct/cpp/shm>./test2.exe
0000xx####xx00##xxxxxxxx0000xx000000xxxxxx00##00############

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值