头文件
cpp
#include <semaphore.h>
创建信号量
对给定的信号量对象进行初始化。
函数原型
cpp
int sem_init(sem_t *sem, int pshared, unsigned int value);
sem:指向要初始化的信号量的指针
pshared:表示信号量的共享方式,0 表示在同一进程的多个线程间共享,非 0 表示在不同进程间共享
value:信号量的初始值
sem_post函数
给信号量的值+1。
函数原型
cpp
int sem_post(sem_t *sem);
参数解释
sem:初始化的信号量对象的指针作为参数,用来改变该对象的值
返回值
成功 :如果 sem_post
函数调用成功,它将返回 0,表示信号量的值已经成功增加,并且可能唤醒了正在等待该信号量的线程。
失败 :如果调用失败,函数将返回 -1,并设置 errno
变量来指示具体的错误原因。
sem_wait函数
从信号量的值-1,但它永远会先等待该信号量为一个非零值才开始做减法
函数原型
cpp
int sem_wait(sem_t *sem);
参数解释
sem:初始化的信号量对象的指针作为参数,用来改变该对象的值
返回值
成功:返回0
sem_destroy函数
用完信号量后,对该信号量进行清理。
归还自己占有的一切资源,在清理信号量的时候如果还有线程在等待他,用户就会收到一个错误。
函数原型
cpp
int sem_destroy(sem_t *sem);
参数解释
sem:初始化的信号量对象的指针作为参数,用来改变该对象的值
返回值
调用成功:返回0
示例
cpp
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <iostream>
#include <semaphore.h>
using namespace std;
// 线程的安全问题:多线程访问共享数据,且对共享数据的操作为非原子性操作(不可能被中断的操作)
int tickets = 10; // 总票数
sem_t sem; // 线程信号量
void* thread_handle2(void* data)
{
char* name = (char*)data;
while (true)
{
sem_wait(&sem);
if (tickets > 0)
{
usleep(1);
printf("%s已出票,剩余票数是:%d\n", name, --tickets);
}
else
{
printf("%s票已售罄\n", name);
break;
}
sem_post(&sem);
}
}
int main()
{
pthread_t thread_id;
int res = sem_init(&sem, 0, 1);
char* s1 = "thread01";
char* s2 = "thread02";
char* s3 = "thread03";
pthread_create(&thread_id, NULL, thread_handle2, s1);
pthread_create(&thread_id, NULL, thread_handle2, s2);
pthread_create(&thread_id, NULL, thread_handle2, s3);
while (true)
{
}
return 0;
}
结果
