进程间通信(十九)——POSIX信号量使用

本文详细介绍了POSIX信号量的概念、API及其使用,涵盖创建、操作、同步和删除信号量的过程。通过示例展示了信号量在亲缘关系和非亲缘关系进程间通信中的应用,以及wait和post操作的实战演示。

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

POSIX信号量

相关API

  • sem_t *sem_open(const char *name, int oflag);
  • sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value)
  • int sem_close(sem_t *sem)
  • int sem_post(sem_t *sem)
  • int sem_wait(sem_t *sem)
  • int sem_trywait(sem_t *sem)
  • int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout)
  • int sem_unlink(const char *name)
  • int sem_getvalue(sem_t *sem, int *sval)

其实信号量就相当于你去游泳馆办理一张卡,办了10次,相当于你有十次游泳机会

你每次去游泳一次信号量减1操作

使用指南

  • 编译时要指定:-lpthread
  • Pthread:
    • POSIX thread,操作线程的API标准
    • 适用于Unix、Linux、Mac、OS

创建出来的信号量在/dev/shm目录下

使用demo.c

int main(int argc, char *argv[])
{
        unsigned int sem_value = 4;
	sem_t *sem = sem_open("posix_sem", O_RDWR|O_CREAT|O_EXCL, 0777, &sem_value);
	if (sem == SEM_FAILED)
	{
		perror("sem_open");
		exit(EXIT_FAILURE);
	}
	if (sem_getvalue(sem, &sem_value) != -1)
		printf("the sem value = %d\n", sem_value);

	sem_wait(sem);
	sem_wait(sem);
	sem_wait(sem);
	sem_wait(sem);
	//sem_wait(sem);

	if (sem_getvalue(sem, &sem_value) != -1)
		printf("the sem value = %d\n", sem_value);
	sem_post(sem);
	sem_post(sem);
	sem_post(sem);
	sem_post(sem);
	sem_post(sem);
	sem_post(sem);
	if (sem_getvalue(sem, &sem_value) != -1)
		printf("the sem value = %d\n", sem_value);

	if (sem_close(sem) != -1)
			printf("close posix sem success\n");

	printf("wait for sem_unlink , 10s~~~~~~~\n");
	sleep(10);

	if (sem_unlink("posix_sem") != 0)
			printf("sem_unlink posix_sem success\n");

	return 0;
}

具有亲缘关系进程间的通信

int main(int argc, char *argv[])
{
	int i = 0;
	int j = 0;
	int ret_fork;
	int sem_value;
	sem_t *sem;
	sem = sem_open(SEM_NAME, O_CREAT, 0666, 1);

	ret_fork = fork();
	if (ret_fork == -1)
	{
		perror("fork");
		sem_close(sem);
		sem_unlink(SEM_NAME);
		exit(EXIT_FAILURE);
	}
	else if (ret_fork == 0)
	{
		while(i++ < 10)
		{
			//sem_trywait(sem);
			sem_wait(sem);
			sem_getvalue(sem, &sem_value);
			printf("child process: sem value = %d\n", sem_value);
			sleep(1);
		}
		exit(EXIT_SUCCESS);
	}
	else if (ret_fork > 0)
	{
		while(j++ < 10)
		{
			sem_post(sem);
			sem_getvalue(sem, &sem_value);
			printf("parent process:sem value = %d\n", sem_value);
			sleep(2);
		}
	}

	sem_close(sem);
	sem_unlink(SEM_NAME);
	return 0;
}

没有亲缘关系的两个进程

int main(int argc, char *argv[])
{
	char *name = "/posix_sem1";
	unsigned int sem_value = 4;
	sem_t *sem = sem_open(name, O_RDWR|O_CREAT, 0777, sem_value);
	if (sem == SEM_FAILED)
	{
		perror("sem_open");
		exit(EXIT_FAILURE);
	}
	printf("sem_open %s success\n", name);

	while(1)
	{
		if (sem_post(sem) == -1)
		{
			perror("sem_post");
			exit(EXIT_FAILURE);
		}
		if (sem_getvalue(sem, &sem_value) != -1)
				printf("post process: sem value = %d\n", sem_value);

		sleep(5);
	}

	sleep(10);

	sem_close(sem);
	if (sem_unlink(name) != -1)
			printf("sem_unlink %s success\n", name);
  
	return 0;
}

wait.c

int main(int argc, char *argv[])
{
	char *name = "/posix_sem1";
	unsigned int sem_value = 4;
	sem_t *sem = sem_open(name, O_RDWR | O_CREAT, 0777,sem_value);
	if (sem == SEM_FAILED)
	{
		perror("sem_open"); 
		exit(EXIT_FAILURE);
	}
	printf("sem_open %s success\n", name);

	while(1)
	{
		if (sem_wait(sem) == -1)
		{
			perror("sem_wait");
			exit(EXIT_FAILURE);
		}
		if (sem_getvalue(sem, &sem_value) != -1)
				printf("wait process: sem value = %d\n", sem_value);
		sleep(1);
	}

	sleep(10);

	if (sem_unlink(name) != -1)
			 printf("sem_unlink %s success\n", name);

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值