当前位置:网站首页>UNIX C language POSIX mutex thread synchronization
UNIX C language POSIX mutex thread synchronization
2022-07-24 11:00:00 【lucky_ poplar】
List of articles
Due to the concurrency of threads , When multiple threads operate on the same global variable at the same time , There will be data inconsistencies .
Therefore, it is necessary to mutually exclusive the operation of global variables in the thread , To ensure that the operation can only be carried out by one thread at the same time , Thus ensuring data security .
Simulate concurrent conflicts
Don't worry about mutexes , First, let's see what problems mutex can solve .
The following code has a int Type num Global variables , Start multiple threads to work on this num Conduct +1 The action of , Every thread +1 perform 1000000 Time , After all threads are executed ,num The value of should be equal to Number of threads *1000000. But because of concurrent execution , The result is less than Number of threads *1000000 Of .
You can run code by yourself .
Note that compilation requires links pthread library :gcc ... -lpthread
#include <pthread.h>
#include <stdio.h>
#include <string.h>
int num = 0; // Global variables
/** * Function executor . similar java Medium Thread#run function . * When the function body is executed , The thread ends . * @param arg Parameters passed in when creating a thread . * @return The result returned by the thread , Can be created by the parent thread of the thread through pthread_join obtain . */
void *thread_proc(void *arg) {
for (int i = 0; i < 1000000; ++i) {
num++;
}
return NULL;
}
int main(void) {
int tcount = 3; // Number of threads
pthread_t tids[tcount];
for (long long i = 1; i <= tcount; ++i) {
// Create multiple threads
int errno = pthread_create(&tids[i - 1], NULL, thread_proc, (void *) i); // Create thread
if (errno) {
// When thread creation fails , Back to errno Not 0
fprintf(stderr, "pthread_create:%s\n", strerror(errno)); // Print exception information
return -1;
}
}
for (int i = 0; i < tcount; ++i) {
pthread_t tid = tids[i];
pthread_join(tid, NULL);
printf(" Threads %lld end .\n", (long long) tid);
}
printf(" All threads are finished ,num=%d\n", num);
getchar();// Prevent the main thread from exiting , Enter to exit .
return 0;
}
The cause of the problem
In code num++ It's a line of code , But actually for CPU It is 3 An instruction operation : take num Load from memory to CPU register 、 register num+1、 register num+1 The value after is written into memory .
Because multiple threads are concurrent at the same time , And stagger the execution of the right num Operation instructions of ,CPU Switch back and forth in the context of the thread num And in memory num Will be inconsistent , Which leads to the final num It is not the correct number according to the number of cycles .
POSIX The mutex of
To solve the above problems , It is necessary to lock the code with concurrent operations and shared data in the thread , Make its operation thread safe .
Mutually exclusive API Thread related API equally , All in <pthread.h> In this header file .
There are two ways to create a mutex , One is static creation , The other is dynamic creation :
- Static creation pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER
- Dynamically create int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); : Create mutexes dynamically int pthread_mutex_destroy(pthread_mutex_t *mutex); : Release dynamically created mutex resources
- Lock and unlock int pthread_mutex_lock(pthread_mutex_t *mutex);: Top mutex int pthread_mutex_unlock(pthread_mutex_t *mutex);: Unlock the mutex
Lock based on the previous problem code , You will find the final num be equal to Number of threads *1000000:
#include <pthread.h>
#include <stdio.h>
#include <string.h>
int num = 0; // Global variables
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // Create mutex statically
/** * Function executor . similar java Medium Thread#run function . * When the function body is executed , The thread ends . * @param arg Parameters passed in when creating a thread . * @return The result returned by the thread , Can be created by the parent thread of the thread through pthread_join obtain . */
void *thread_proc(void *arg) {
for (int i = 0; i < 1000000; ++i) {
pthread_mutex_lock(&mutex); // locked
num++;
pthread_mutex_unlock(&mutex); // Unlock
}
return NULL;
}
int main(void) {
int tcount = 3;
pthread_t tids[tcount];
for (long long i = 1; i <= tcount; ++i) {
// Create multiple threads
int errno = pthread_create(&tids[i - 1], NULL, thread_proc, (void *) i); // Create thread
if (errno) {
// When thread creation fails , Back to errno Not 0
fprintf(stderr, "pthread_create:%s\n", strerror(errno)); // Print exception information
return -1;
}
}
for (int i = 0; i < tcount; ++i) {
pthread_t tid = tids[i];
pthread_join(tid, NULL);
printf(" Threads %lld end .\n", (long long) tid);
}
printf(" All threads are finished ,num=%d\n", num);
getchar();// Prevent the main thread from exiting , Enter to exit .
return 0;
}
边栏推荐
- Overview of basic knowledge of binary tree
- The bean injected through @autowired can still be injected even if the class is not annotated with annotations such as @comment
- Value and technical thinking of vectorization engine for HTAP
- Modbus RTU通讯协议详解与实例演示
- [live registration] analysis of location cache module and detailed explanation of OCP monitoring and alarm
- [FPGA]: IP core - multiplier
- openresty lua-resty-logger-socket日志传输
- Dialogue ace phase IV: challenges and opportunities for the future development of distributed databases
- QT application prevents multiple opening, that is, single instance operation
- Zero basic learning canoe panel (10) -- checkbox
猜你喜欢

cookie sessionStorage localStorage 区别

神器 ffmpeg —— 操作视频,极度舒适

PC Museum (2) 1972 hp-9830a

Redismission watchdog implementation mechanism can be understood at a glance

UVM - two way communication

Download path of twincat3 versions

2018 arXiv | Objective-Reinforced Generative Adversarial Networks (ORGAN) for Sequence Generation Mo

Artifact ffmpeg - operation video, extremely comfortable

Working principle and function application of frequency converter
![[personal summary] end of July 17, 2022](/img/56/8c69b171140ca38e16f0bbb7f344e3.jpg)
[personal summary] end of July 17, 2022
随机推荐
38. REM adaptive layout
[micro service] eureka+ribbon realizes registration center and load balancing
Detailed explanation of the implementation process of redistribution watchdog
Development and course of Bluetooth Technology
零基础学习CANoe Panel(6)—— 开关/显示控件(Switch/Indicator)
Partition data 2
跨平台音频播放库
Modbus RTU通讯协议详解与实例演示
Summary of const type data
零基础学习CANoe Panel(4)——按钮(Button )
Cross platform audio playback Library
变频器的四大组成部分和工作原理
PC Museum (1) 1970 datapoint 2000
Activity review | Anyuan AI X machine heart series lecture No. 1 | deepmind research scientist rohin Shah shares "finding a safe path for AgI"
Web salted fish self rescue strategy -- typescript classes are not as difficult as you think
零基础学习CANoe Panel(10)—— 复选框(CheckBox)
Machine learning quiz (11) verification code recognition test - deep learning experiment using QT and tensorflow2
新式拥塞控制漫谈
零基础学习CANoe Panel(7)—— 开关/显示控件(Input/Output Box )
[personal summary] end of July 17, 2022