Linux multithreading and synchronization between threads[Copy link]
1. The difference between process and thread The purpose of process is to serve as the basic unit for allocating system resources (CPU time, memory, etc.). A thread is an execution flow of a process and the basic unit for CPU scheduling and dispatching. It is a smaller basic unit that can run independently than a process. A process consists of several threads, and threads share all the resources owned by the process with other threads belonging to the same process. Address space: A process has an independent address space, including a text region, a data region, and a stack region. When a process crashes, it will not affect other processes in protected mode. A thread is just a different execution path in a process. A thread has its own stack and local variables (essential resources during operation), but there is no separate address space between threads. If a thread dies, the entire process dies. Threads in the same process share the address space of the process. Communication: Inter-process communicationIPC, threads can directly read and write process data segments (such as global variables) to communicate - process synchronization and mutual exclusion means are required to ensure data consistency. Scheduling and switching: Thread context switching is much faster than process context switching. In a multithreadedOS, a process is not an executable entity. Address space: An execution unit within a process; a process has at least one thread; they share the address space of the process; and the process has its own independent address space; Resource ownership: A process is the unit of resource allocation and ownership. Threads within the same process share the resources of the process Threads are the basic unit of processor scheduling, but processes are not. Both can be executed concurrently. 2. Reasons for using threads In Linux, when starting a new process, it must be allocated an independent address space, and many data tables must be established to maintain its code segment, stack segment, and data segment. This is an "expensive" way of multitasking. Multiple threads running in a process use the same address space and share most of the data. The space spent on starting a thread is much smaller than the space spent on starting a process, and the time required to switch between threads is also much smaller than the time required to switch between processes. Convenient communication mechanism between threads. Different processes have independent data spaces, and data can only be transferred through communication, which is not only time-consuming but also inconvenient. This is not the case with threads. Since threads under the same process share data space, the data of one thread can be directly used by other threads, which is not only fast but also convenient. 3. Thread operation function #include int pthread_create(pthread_t *[/font ]tid, const pthread_attr_t *attr, void *(*func) (void *), void *arg); int pthread_join (pthread_t tid, void ** status); pthread_t pthread_self (void); [/ font] int pthread_detach (pthread_t tid); void pthread_exit (void *status ); pthread_create: used to create a thread, returns 0 if successful, otherwise returns Exxx (a positive number). =Tahoma] pthread_t *tid: The type of thread id is pthread_t, usually an unsigned integer. When it is returned through the *tid pointer. const pthread_attr_t *attr: Specifies the attributes of the created thread, such as thread priority, initial stack size, whether it is a daemon process, etc. You can use NULL to use the default value, usually In most cases we use the default value. void *(*func) (void *): Function pointer func, specifies the function to be executed when a new thread is created. [size =10.5pt] void *arg: The thread will execute The function's arguments. The significance of learning embedded systems is that it is easy to learn after a long time. If you want to pass multiple parameters, please separate themPackaging In a structure. pthread_join: used to wait for a thread to exit, returns 0 if successful, otherwise returns Exxx (a positive number). pthread_t tid: specifies the thread ID to wait for ] [size =10.5pt]void ** status: If it is not NULL, then the thread's return value is stored in the space pointed to by status (this is why status is a secondary pointer! This kind of parameter is also called "value-result" parameters). [ pthread_self: used to return the ID of the current thread. pthread_detach: Used to specify that the thread becomes detached. It is similar to a process detaching from a terminal and becoming a background process. If successful, it returns 0, otherwise it returns Exxx (a positive number). If the thread becomes a detached thread, all its resources will be released if the thread exits. If it is not a detached thread, the thread It must retain its thread ID and exit status until another thread calls pthread_join on it. pthread_exit is used to terminate a thread. You can specify a return value so that other threads can obtain the return value of the thread through the pthread_join function. void *status: pointer to the return value of the thread termination. 4. Mutual exclusion between threads Using mutex locks (mutual exclusion) allows threads to execute in sequence. Typically, mutex locks synchronize multiple threads by ensuring that only one thread executes a critical section of code at a time. Mutex locks can also protect single-threaded code. int pthread_mutex_lock(pthread_mutex_t * mptr); int pthread_mutex_unlock(pthread_mutex_t * mptr); First declare a variable of type pthread_mutex_t, which will be used as the parameter of the following two functions. Before operating on critical resources, pthread_mutex_lock needs to be locked first, and pthread_mutex_unlock needs to be unlocked after the operation. 5. Inter-thread synchronization Condition variables: Condition variables can be used to atomically block threads until a specific condition is true. Condition variables are always used with mutex locks. The test of the condition is performed under the protection of the mutex lock (mutual exclusion). #include int pthread_cond_wait(pthread_cond_t *cptr, pthread_mutex_t *mptr); int pthread_cond_signal(pthread_cond_t *cptr); //Both return: 0 if OK, positive Exxx value on error pthread_cond_wait is used to wait for a certain condition to be true, and pthread_cond_signal is used to notify the blocked thread that a certain condition is true. Before the two functions, a variable of type pthread_cond_t needs to be declared to be used as the parameter of the two functions. =Tahoma]/* Are you familiar with POSIX multi-threaded programming techniques? If you are familiar with it, write a program to complete the following functions: 1) There is a The initial value of the int type global variable g_Flag is 0; 2) Start thread 1 in the main thread, print "this is thread1", and set g_Flag to 1 =Tahoma] 3) Start thread 2 in the main thread, print "this is thread2", and set g_Flag to 2 ] 4) Thread 1 needs to exit after thread 2 exits. ] 5) The main thread exits when it detects that g_Flag changes from 1 to 2, or from 2 to 1