POSIX无名信号量一般用于线程间,其基本使用步骤如下:
(1)在线程都能访问到的区域定义信号量变量(如全局变量),类型是sem_t。
(2)在任何线程使用它之前,用sem_init()初始化它。
(3)使用sem_wait()/sem_trywait()和sem_post()来分别进行P操作,V操作。
(4)不再需要时,使用sem_destroy()来销毁它。
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
#include <string.h>
// 定义信号量
sem_t sem_w; // 可读信号量
sem_t sem_r; // 可写信号量
char buf[100] = {};
/* 线程响应函数--写 */
void *routine_w(void *arg)
{
printf("进入写线程成功!\n");
// P/V操作
while(1)
{
//P操作,申请资源,-1
int ret = sem_wait(&sem_w);
if (ret == -1)
{
printf("申请资源失败!\n");
break;
}
printf("写线程写入数据:");
//访问资源
scanf("%s", buf);
//V操作,释放资源,+1
sem_post(&sem_r);
if (strcmp(buf, "exit") == 0) // 输入exit退出写线程
{
break;
}
}
pthread_exit(NULL);
}
/* 线程响应函数--读 */
void *routine_r(void *arg)
{
printf("进入读线程成功!\n");
//P/V操作
while(1)
{
//P操作,申请资源,-1
int ret = sem_wait(&sem_r);
if (ret == -1)
{
printf("申请资源失败!\n");
break;
}
//访问资源
printf("读线程读到的信息:%s\n", buf);
//V操作,释放资源,+1
sem_post(&sem_w);
if (strcmp(buf, "exit") == 0)
{
break;
}
}
pthread_exit(NULL);
}
int main(int argc, char const *argv[])
{
// 定义线程id
pthread_t w_tid, r_tid;
// 初始化信号量, 可写设为1, 可读设为0
sem_init(&sem_w, 0, 1);
sem_init(&sem_r, 0, 0);
// 创建新线程
pthread_create(&w_tid, NULL, routine_w, NULL);
pthread_create(&r_tid, NULL, routine_r, NULL);
printf("我是主线程,线程创建成功!\n");
pthread_join(w_tid, NULL); // 若w_tid写线程没有退出,阻塞等待
pthread_join(r_tid, NULL); // 若r_tid读线程没有退出,阻塞等待
// 销毁线程
sem_destroy(&sem_w);
sem_destroy(&sem_r);
return 0;
}