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;
}
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐