sem_wait
是 POSIX 标准中定义的一个用于同步的函数,它通常用于操作信号量(semaphore)。信号量是一个整数变量,可以用来控制对共享资源的访问。在多线程编程中,sem_wait
常用于实现线程间的同步。
概念
sem_wait
的基本作用是减少信号量的值。如果信号量的值大于零,那么 sem_wait
会将其减一,然后立即返回。如果信号量的值为零,则 sem_wait
会阻塞,直到信号量的值变为大于零,此时函数才会将其减一,并解除阻塞。
这里有两个重要的概念:
- 二进制信号量:其值只能是 0 或 1,通常用于互斥(mutex)。
- 计数信号量:其值可以是任何非负整数,常用于表示资源的可用数量。
使用案例
以下是一个简单的使用 sem_wait
和 sem_post
的例子,用于在两个线程之间同步。
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
sem_t sem;
void* thread_func(void* arg) {// 等待信号量sem_wait(&sem);printf("线程 %ld 获取了信号量。\n", (long)arg);// 模拟做一些工作sleep(1);// 释放信号量sem_post(&sem);return NULL;
}
int main() {pthread_t threads[2];sem_init(&sem, 0, 1); // 初始化信号量为1// 创建两个线程for (long i = 0; i < 2; ++i) {if (pthread_create(&threads[i], NULL, thread_func, (void*)i) != 0) {perror("pthread_create");return 1;}}// 等待线程结束for (int i = 0; i < 2; ++i) {pthread_join(threads[i], NULL);}sem_destroy(&sem); // 销毁信号量return 0;
}
在这个例子中:
sem_init
初始化一个信号量,其初始值为 1。- 每个线程在开始执行任务前都会调用
sem_wait
,这确保了同一时刻只有一个线程可以执行任务。 - 当线程完成任务后,它会调用
sem_post
来增加信号量的值,从而允许其他线程继续执行。
注意事项
- 使用信号量时,一定要确保在任何可能阻塞的
sem_wait
调用之后,都有对应的sem_post
调用来释放信号量,以避免死锁。 - 在多线程程序中,正确地初始化和销毁信号量是非常重要的。
- 信号量是进程间或线程间同步的一种机制,使用时要确保所有可能访问该信号量的线程或进程都遵循相同的协议。