multithreading - 在多线程环境中在 sem_wait 之前调用 sem_post
问题描述
对于基于二进制信号量的实现,该sem_post()
函数的行为尚不清楚。
sem_wait()
打电话后打电话会发生什么sem_post()
。它会起作用吗。
代码示例:
线程 1:
do_something_critical()
sem_post();
线程 2:
sem_wait()
Proceed()
在这里,如果sem_post()
在调用 to 之前调用了一些方法sem_wait()
,它会起作用吗?还是有必要sem_wait()
在之前调用sem_post()
?
解决方案
sem_post()只是增加信号量并唤醒任何等待线程(如果有)。否则它什么也不做。
sem_wait()只是减少信号量。仅当信号量的当前值为 0 时,调用方才会被阻塞。
这是一个示例程序,其中主线程将信号量初始化为 0,并调用sem_trywait()来验证信号量是否忙(即值为 0)。然后,它调用sem_post()在创建线程之前释放信号量(即值为 1)。线程调用sem_wait()(这将信号量减为 0)并返回。主线程等待线程结束并通过调用sem_trywait()验证信号量是否为 0 :
#include <pthread.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <semaphore.h>
#include <stdio.h>
#include <errno.h>
static sem_t *sem;
void *thd_entry(void *p)
{
int rc;
printf("Thread is starting...\n");
// This decrements the semaphore
rc = sem_wait(sem);
if (0 != rc) {
perror("sem_wait()");
return NULL;
}
printf("Thread is exiting...\n");
return NULL;
}
int main(int ac, char *av[])
{
int rc;
pthread_t thd;
// Create a semaphore with an initial value set to 0
sem = sem_open("/example", O_CREAT|O_RDWR, 0777, 0);
if (sem == SEM_FAILED) {
perror("sem_open()");
return 1;
}
// After creation the value of the semaphore is 0
rc = sem_trywait(sem);
if (-1 == rc) {
if (errno == EAGAIN) {
printf("Semaphore is busy (i.e. value is 0)\n");
} else {
perror("sem_trywait()");
return 1;
}
}
// Increment the semaphore
rc = sem_post(sem);
if (0 != rc) {
perror("sem_post()");
return 1;
}
// Create a thread
rc = pthread_create(&thd, NULL, thd_entry, 0);
if (0 != rc) {
errno = rc;
perror("pthread_create()");
return 1;
}
rc = pthread_join(thd, NULL);
if (0 != rc) {
errno = rc;
perror("pthread_join()");
return 1;
}
// The semaphore is 0 as the thread decremented it
rc = sem_trywait(sem);
if (-1 == rc) {
if (errno == EAGAIN) {
printf("Semaphore is busy (i.e. value is 0)\n");
} else {
perror("sem_trywait()");
return 1;
}
}
return 0;
}
这是一个尝试:
$ ls -l /dev/shm
total 0
$ gcc sema.c -o sema -lpthread
$ ./sema
Semaphore is busy (i.e. value is 0)
Thread is starting...
Thread is exiting...
Semaphore is busy (i.e. value is 0)
$ ls -l /dev/shm
total 4
-rwxrwxr-x 1 xxxxx xxxxx 32 janv. 5 16:24 sem.example
$ rm /dev/shm/sem.example
推荐阅读
- python - 类属性的链表
- networking - 丢弃的大 UDP 多播消息
- javascript - JavaScript 调用类的默认值
- list - API 工作但返回类名的实例
- java - 用于轻松生成 xpath 的类
- c# - 如何将一堆 json 文件合并到一个大文件中?
- java - Java:有没有转换ArrayList的方法
到 boolean[] (原始数组)? - flutter - Flutter,第二个动画控制器没有动画,为什么?
- c# - 使用相同库 api 的 Rabbitmq 的性能非常不同(python3 与 dotnet)
- perl - 在perl中没有数组的情况下以相反的顺序搜索段落