当前位置:网站首页>Semaphore of thread synchronization
Semaphore of thread synchronization
2022-06-27 13:50:00 【StudyWinter】
1 Basic concepts
- Simply put, it is an evolutionary version of mutual exclusion (1~N) Counter
- Record the number of resources currently available , Current resource quantity <=0 It's going to block up when it's time , Current resource quantity > Start the operation only when , In addition, semaphore operations are all atomic operations .
Due to the large granularity of mutex , If we want to share some data of an object among multiple threads , There is no way to use mutexes , Only the entire data object can be locked . In this way, the purpose of ensuring the correctness of data when multi-threaded operation shares data is achieved , But it virtually leads to the decrease of thread concurrency . Threads execute from parallel , It becomes serial execution . It's no different from using a single process directly . Semaphore , It's a relative compromise , It can ensure synchronization , The data is not chaotic , It can also improve thread concurrency .
2 Function USES
2.1 sem_init function
effect : Initialize a semaphore
int sem_init(sem_t *sem, int pshared, unsigned int value);
// ginseng 1:sem Semaphore
// ginseng 2:pshared take 0 Used between threads ; Take the 0( It's usually 1) Used between processes
// ginseng 3:value Specifies the initial value of the semaphore The initial value of the semaphore , Determines which threads occupy semaphores ( process ) The number of .
2.2 sem_destroy function
effect : Destroy a semaphore
int sem_destroy (sem_t *sem);2.3 sem_wait function
effect : Lock the semaphore --
int sem_wait(sem_t *sem);2.4 sem_post function
effect : Unlock the semaphore ++
int sem_post(sem_t *sem);2.5 sem_trywait function
effect : Try to lock the semaphore – ( And sem_wait The difference between lock and trylock)
int sem_trywait(sem_t *sem);2.6 sem_timedwait function
effect : Try to lock the semaphore for a limited time --
int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);
// ginseng 2:abs_timeout Absolute time is used .3 Semaphores are implemented by producers and consumers

According to the notes , The code is easy to understand . Two semaphores to control , One starts with 0, Indicates that the initial production quantity is 0. Another initial quantity is the number of spaces where goods can be stored , Initialization is the number of cells N.
Mutually exclusive and conditional variables are the way I consume You can't produce . And two semaphores are produced by you I can spend . After all, circular does not affect , At most you produced , I don't know . Afraid of multiple producers , You put it in the grid and I put it again before moving to the next grid .
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#define NUM 5
int queue[NUM]; // The global array simulation implements the ring queue
sem_t black_number, product_number; // Empty lattice semaphore . Product semaphore
// Producer callback function
void* producer(void* arg) {
int i = 0;
int res = 0;
while (1) {
// Lock the empty cell semaphore , Subtract one from the number of spaces , by 0 Then block and wait
res = sem_wait(&black_number);
if (res != 0) {
fprintf(stderr, "sem_wait black_number error:%s\n", strerror(res));
exit(1);
}
// Simulate the production of a product
queue[i] = rand() % 1000 + 1;
printf("------Produce---%d\n", queue[i]);
// Product semaphore unlock , Put the product ++
res = sem_post(&product_number);
if (res != 0) {
fprintf(stderr, "sem_post product_number error:%s\n", strerror(res));
exit(1);
}
i = (i + 1) % NUM;
sleep(rand() % 2);
}
}
// Consumer callback function
void* consumer(void* arg) {
int i = 0;
int res = 0;
while (1) {
// Consumers will increase the number of products --, by 0 Then block and wait
res = sem_wait(&product_number);
if (res != 0) {
fprintf(stderr, "sem_wait product_number error:%s\n", strerror(res));
exit(1);
}
printf("==============================Consumer=========%d\n", queue[i]);
// Consume a product
queue[i] = 0;
// After consumption, add the number of spaces ++
res = sem_post(&black_number);
if (res != 0) {
fprintf(stderr, "sem_post black_number error:%s\n", strerror(res));
exit(1);
}
// Simulate a circular queue
i = (i + 1) % NUM;
sleep(rand() % 5);
}
}
int main(int argc, char** argv) {
// Producer thread and consumer thread
pthread_t pid, cid;
// Initialize empty lattice semaphore , The semaphore is 5, Sharing between threads ----0
int res = sem_init(&black_number, 0, NUM);
if (res != 0) {
fprintf(stderr, "sem_init black_number error:%s\n", strerror(res));
exit(1);
}
// Initialize the product semaphore , The number of products is 0
res = sem_init(&product_number, 0, 0);
if (res != 0) {
fprintf(stderr, "sem_init product_number error:%s\n", strerror(res));
exit(1);
}
// Create a producer thread
res = pthread_create(&pid, NULL, producer, NULL);
if (res != 0) {
fprintf(stderr, "pthread_create producer error:%s\n", strerror(res));
exit(1);
}
// Create consumer thread
res = pthread_create(&cid, NULL, consumer, NULL);
if (res != 0) {
fprintf(stderr, "pthread_create consumer error:%s\n", strerror(res));
exit(1);
}
// Recycle thread
res = pthread_join(pid, NULL);
if (res != 0) {
fprintf(stderr, "pthread_join producer error:%s\n", strerror(res));
exit(1);
}
res = pthread_join(cid, NULL);
if (res != 0) {
fprintf(stderr, "pthread_join consumer error:%s\n", strerror(res));
exit(1);
}
// Destroy semaphore
res = sem_destroy(&black_number);
if (res != 0) {
fprintf(stderr, "sem_destroy black_number error:%s\n", strerror(res));
exit(1);
}
res = sem_destroy(&product_number);
if (res != 0) {
fprintf(stderr, "sem_destroy product_number error:%s\n", strerror(res));
exit(1);
}
return 0;
}perform

边栏推荐
- IJCAI 2022 | greatly improve the effect of zero sample learning method with one line of code. Nanjing Institute of Technology & Oxford proposed the plug and play classifier module
- ensp云朵配置
- Debug tool
- Implementing springboard agent through SSH port forwarding configuration
- 【PHP代码注入】PHP语言常见可注入函数以及PHP代码注入漏洞的利用实例
- 快讯:华为启动鸿蒙开发者大赛;腾讯会议发布“万室如意”计划
- 为什么 Oracle 云客户必须在Oracle Cloud 季度更新发布后自行测试?
- [安洵杯 2019]Attack
- Is there any discount for opening an account now? Is it safe to open an account online?
- Cesium实现卫星在轨绕行
猜你喜欢
Kotlin函数使用示例教程

Kyndryl partnered with Oracle and Veritas

crane:字典项与关联数据处理的新思路

NAACL 2022 | TAMT:通过下游任务无关掩码训练搜索可迁移的BERT子网络
![[business security 03] password retrieval business security and interface parameter account modification examples (based on the metinfov4.0 platform)](/img/29/73c381f14a09ecaf36a98d67d76720.png)
[business security 03] password retrieval business security and interface parameter account modification examples (based on the metinfov4.0 platform)

Firewall foundation Huawei H3C firewall web page login

What else can PLM do?
![[business security-02] business data security test and example of commodity order quantity tampering](/img/0f/c4d4dd72bed206bbe3e15e32456e2c.png)
[business security-02] business data security test and example of commodity order quantity tampering

【业务安全03】密码找回业务安全以及接口参数账号修改实例(基于metinfov4.0平台)

【周赛复盘】LeetCode第81场双周赛
随机推荐
PCL库——报错解决:安装时遇到的cmake与anaconda的冲突问题
赛迪顾问发布《“十四五” 关键应用领域之数据库市场研究报告》(附下载)
【mysql进阶】MTS主从同步原理及实操指南(七)
POSIX AIO -- Introduction to glibc version asynchronous IO
How to solve the problem of missing language bar in win10 system
Why must Oracle cloud customers self test after the release of Oracle cloud quarterly update?
awk 简明教程
Kyndryl partnered with Oracle and Veritas
jvm 参数设置与分析
Daily question brushing record (6)
Redis持久化
力扣 第 81 场双周赛
scrapy
每日3题(2):检查二进制字符串字段
[WUSTCTF2020]girlfriend
[weekly replay] the 81st biweekly match of leetcode
MySQL locking mechanism and four isolation levels
How to set postman to Chinese? (Chinese)
American chips are hit hard again, and another chip enterprise after Intel will be overtaken by Chinese chips
图书管理系统