
信号量:程序员之间的“红绿灯”
AI-摘要
Tianli GPT
AI初始化中...
介绍自己
生成本文简介
推荐相关文章
前往主页
前往tianli博客
信号量
1.1 概述
信号量广泛用于【线程】和【进程】之间的互斥行为。****信号本质上一个【非负数整数计数器】,用于管理控制线程或者进程之间的共享资源访问问题。
- 当信号量大于 0 时,当前线程或者进程可以访问对应的共享资源。
- 当前信号量为 0 时,当前线程或者进程,处于阻塞状态。
- 核心内容是 PV 操作,P 操作信号量 - 1 ,V 操作信号量 + 1
1.2 信号量对应函数
1.2.1 信号量数据类型
sem_t 在 <semaphore.h> 头文件中
typedef union { char __size[__SIZEOF_SEM_T]; long int __align; } sem_t;
1.2.2 sem_init 初始化
函数文档
#include <semaphore.h> int sem_init(sem_t *sem, int pshared, unsigned int value)
- 函数功能:
- 用于初始化一个信号量变量,提供必要的参数,限制当前信号量是针对于【线程操作】还是【进程操作】
- 函数参数
sem_t *sem :
信号量变量地址int pshared :
控制值当前信号量,限制内容为线程还是进程,线程参数要求为 0, 不等于 0 为进程间操作。建议 0 线程, 1 进程。unsigned int value :
信号量初始化数据,通常情况下为 1- 返回值
- 成功返回 0
- 失败返回 -1
1.2.3 sem_wait P 操作/等待操作
函数文档
#include <semaphore.h> int sem_wait(sem_t *sem)
- 函数功能:
- 信号量 P 操作,当前信号量 -= 1。
- 如果为 0 当前线程/进程进入阻塞状态。
- 如果不为 0,信号量 -= 1,同时可以执行目标线程/进程代码。
- 函数参数:
sem_t *sem :
信号量变量地址- 返回值类型
- 成功返回 0
- 失败返回 -1
1.2.4 sem_post V 操作/释放操作
函数文档
#include <semaphore.h> int sem_post(sem_t *sem)
- 函数功能:
- 信号量 V 操作,当前信号量 += 1
- 信号量不为 0,相当于解除与当前信号量相关的其他线程/进程****阻塞状态
- 函数参数:
sem_t *sem :
信号量变量地址- 返回值类型
- 成功返回 0
- 失败返回 -1
1.2.5 sem_destroy 销毁操作
函数文档
#include <semaphore.h> int sem_destroy (sem_t *sem)
- 函数功能:
- 销毁当前信号量变量
- 函数参数:
sem_t *sem :
信号量变量地址- 返回值类型
- 成功返回 0
- 失败返回 -1
信号量互斥
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
// 信号量【互斥】
sem_t sem;
void printf_value(char *str);
void *thread_funcationA(void *arg);
void *thread_funcationB(void *arg);
int main(int argc, char const *argv[])
{
// 信号量初始化
sem_init(&sem, 0, 1);
pthread_t td1 = 0;
pthread_t td2 = 0;
pthread_create(&td1, NULL, thread_funcationA, "Hello World!");
pthread_create(&td2, NULL, thread_funcationB, "C/C++ best in the world!");
pthread_join(td1, NULL);
pthread_join(td2, NULL);
// 信号量销毁
sem_destroy(&sem);
return 0;
}
void *thread_funcationA(void *arg)
{
// 信号量 P 操作
sem_wait(&sem);
printf_value((char *)arg);
// 信号量 V 操作
sem_post(&sem);
}
void *thread_funcationB(void *arg)
{
// 信号量 P 操作
sem_wait(&sem);
printf_value((char *)arg);
// 信号量 V 操作
sem_post(&sem);
}
void printf_value(char *str)
{
while (*str != '\0')
{
printf("%c", *str);
fflush(stdout);
sleep(1);
str += 1;
}
printf("\n");
}
信号量同步
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
// 信号量【同步】
// 可以利用信号量同步,控制线程的执行次序,从而保证项目启动,执行任务一致性。
sem_t sem1, sem2, sem3;
void printf_value(char *str);
void *thread_funcationA(void *arg);
void *thread_funcationB(void *arg);
void *thread_funcationC(void *arg);
int main(int argc, char const *argv[])
{
sem_init(&sem1, 0, 1);
sem_init(&sem2, 0, 0);
sem_init(&sem3, 0, 0);
pthread_t td1 = 0;
pthread_t td2 = 0;
pthread_t td3 = 0;
pthread_create(&td1, NULL, thread_funcationA, "Hello");
pthread_create(&td2, NULL, thread_funcationB, "World");
pthread_create(&td3, NULL, thread_funcationC, "!!!");
pthread_join(td1, NULL);
pthread_join(td2, NULL);
pthread_join(td3, NULL);
sem_destroy(&sem1);
sem_destroy(&sem2);
sem_destroy(&sem3);
return 0;
}
void *thread_funcationA(void *arg)
{
// 信号量 P 操作
sem_wait(&sem1);
printf_value((char *)arg);
// 信号量 V 操作
sem_post(&sem2);
}
void *thread_funcationB(void *arg)
{
// 信号量 P 操作
sem_wait(&sem2);
printf_value((char *)arg);
// 信号量 V 操作
sem_post(&sem3);
}
void *thread_funcationC(void *arg)
{
// 信号量 P 操作
sem_wait(&sem3);
printf_value((char *)arg);
// 信号量 V 操作
sem_post(&sem1);
}
void printf_value(char *str)
{
while (*str != '\0')
{
printf("%c", *str);
fflush(stdout);
sleep(1);
str += 1;
}
printf("\n");
}
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载必须注明来自 卡卡罗特
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果