当前位置:网站首页>Learning notes for introduction to C language multithreaded programming
Learning notes for introduction to C language multithreaded programming
2022-07-01 03:22:00 【Twilight dust remains】
Catalog
Learning materials
Recently, I am learning about multithreaded programming , Learned some basic knowledge of multithreading , recorded
Website URL: https://www.bilibili.com/video/BV1kt411z7ND/
Website title : [C Language ] Introduction to multithreaded programs
Threads and processes
Both can be computed in parallel , But threads can share memory , But processes cannot share memory .
For example, different threads carry out a++, Then the same one is added a
But different processes go on a++, It's different a
When we use thread parallel computing , We can calculate at the same time by dividing large tasks into small tasks , For example, calculation 1-5000 Summation of , We can use a thread to calculate 1-2500, Another thread calculates 2501-5000, Finally, the two numbers are added together to achieve the overall task .
pthread_create
#include <stdio.h>
#include <stdlib.h>
#include <phread.h>
void* myfunc(void* args)
{
printf("hello world");
return NULL;
}
int main(){
pthread_t th;
pthread_create(&th, NULL,myfunc, NULL);
}
In multithreaded programming , We need to use pthread_create Create thread . The first parameter is the name of the thread , The second parameter generally does not require , The third parameter is the function we want to run in this thread , The last one is the parameter passed to the thread .
Be careful ! If the code is multithreaded , When compiling, you need to add -lpthread
If thread is not finished , When the main thread has finished , It will cause the main thread to shut down the thread directly , No more execution
pthread_join
Word functions can wait for the thread to finish running before exiting the main thread
// Single thread waiting
pthread_join(th, NULL);
// Multiple threads waiting
pthread_join(th2, NULL);
pthread_join(th2, NULL);
Pass parameters
We're going to take the pthread_start Change the parameters , Change it to pthread_create(&th, NULL,myfunc, "th1");
such , It's going to take the parameters "th1" Pass to void* myfunc(void* args) Untyped variables in args
At this time, how do we apply the passed variables ? We just need a forced type conversion OK.
Here is an application scenario , utilize void Receive variables of unknown type .
void, In fact, it points to a memory address , No matter what variable you pass , You can use void* To make a point , In the following , We can pass parameters by performing a forced type conversion according to variables , Because the memory has not changed , We just changed the way of explanation .
How to use
In that case , thatvoid*What's the use ? In fact, we will find that their parameter types arevoid*, for example :
ssize_t read(int fd, void *buf, size_t count);
void *memcpy(void *dest, const void *src, size_t n);
Why design like this ? Because for this universal interface , You don't know what the user's data type is , But you have to be able to handle all types of user data , So I will use
void*.void*Can accept all types of pointers with tolerance . in other words , If you expect the interface to accept any type of parameter , You can usevoid*type . But in the specific use of , You must convert to a specific pointer type . for example , What you pass into the interface isint*, Then you should followint*Use .
Be careful
Usevoid*Here's the thing to watch out for , You must know what type of original incoming , Then convert to the corresponding type .
You know ——void* What kind of existence
Parameter transfer instance
#include <stdio.h>
#include <stdlib.h>
#include <phread.h>
void* myfunc(void* args)
{
int i;
char* name = (char*) args;
for(i=1; i<50; i++){
printf("%s":"%d\n", name, i);
}
return NULL;
}
int main(){
pthread_t th1,th2;
pthread_create(&th1, NULL,myfunc, "th1");
pthread_create(&th2, NULL,myfunc, "th2");
}
In this way, two threads output numbers , And realize the transfer of character variables .
Transfer of multiple parameters
If we need to pass multiple parameters , We can integrate multiple parameters into one structure , Then it can be forcibly converted to the structure variable . This method can also save the functions we define , Use the same function to achieve different effects according to different variables .
for example :MY_ARGS args = (MY_ARGS*) args
The return of the parameter
According to the principle of the previous article , We can also define a variable in the structure result, At the end of the thread , Pass the result , Thus, an effect similar to the return of function parameters is realized
race condition situation
Be careful , Different threads should not perform an operation on a global variable , For the following reasons :
This is the time when race condition The situation of
such as , Two threads , At the same time, for a global variable s Cycle are s++ The operation of
Then the operations of the two threads are as follows : Read s Variable memory --> The read value is ++ operation --> take ++ The subsequent value is written back to memory
This may lead to a situation , When one of the threads has finished reading s Variable but not written back to memory , Another thread also reads this memory , And operate , So the two threads compete , Which leads to inaccurate final results .
resolvent —— Lock :mutex
You can define a variable of this type pthread_mutex_t lock
We need to initialize the lock before using it pthread_mutex_init(&lock, NULL), The second variable can be used first NULL Instead of
Lock pthread_mutex_lock(&lock)
Unlock pthread_mutex_unlock(&lock)
Only this process gets the lock , Only when it is locked can it continue to run , Another process can only wait for this process to unlock before it can get the lock to run .
But if we lock and unlock the program too often, the actual running time of the program will be too long .
False Sharing
When calculating , If the interval between variables used by the cores of multiple threads is very close , There will be a false sharing , The specific situation is CPU In order to calculate fast , Generally, the variables of the adjacent paths of the variables that need to be used are put into the cache , In this way, if two threads use two similar variables, they will read them into their own kernel , Put it back after treatment , When you put it back, there will be differences between adjacent variables , This leads to a waste of reading and writing speed , This leads to a waste of time .
边栏推荐
- 彻底解决Lost connection to MySQL server at ‘reading initial communication packet
- EtherCAT原理概述
- 咱就是说 随便整几千个表情包为我所用一下
- The best learning method in the world: Feynman learning method
- If a parent class defines a parameterless constructor, is it necessary to call super ()?
- Druid monitoring statistics source
- C#实现图的深度优先遍历--非递归代码
- 实战 ELK 优雅管理服务器日志
- Is it safe to open an account online in a small securities firm? Will my money be unsafe?
- mybati sql 语句打印
猜你喜欢
随机推荐
Introduction to core functions of webrtc -- an article on understanding SDP PlanB unifiedplan (migrating from PlanB to unifiedplan)
go实现命令行的工具cli
Pytest -- plug-in writing
服务器渲染技术jsp
How to use hybrid format to output ISO files? isohybrid:command not found
数据交换 JSON
[us match preparation] complete introduction to word editing formula
Classic programming problem: finding the number of daffodils
CX5120控制汇川IS620N伺服报错E15解决方案
Completely solve the lost connection to MySQL server at 'reading initial communication packet
世界上最好的学习法:费曼学习法
XXL job User Guide
shell脚本使用两个横杠接收外部参数
雪崩问题以及sentinel的使用
# 使用 KubeKey 搭建 Kubernetes/KubeSphere 环境的'心路(累)历程'
EtherCAT原理概述
Redis 教程
第03章_用户与权限管理
EDLines: A real-time line segment detector with a false detection control翻译
Elk elegant management server log







