In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-27 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
Editor to share with you the example analysis of thread mutex locks in Linux, I believe that most people do not know much about it, so share this article for your reference, I hope you can learn a lot after reading this article, let's go to know it!
In programming, the concept of object mutex is introduced to ensure the integrity of shared data operations. Each object corresponds to a tag that can be called a mutex, which is used to ensure that only one thread can access the object at any one time. The mutex mechanism implemented by Linux includes POSIX mutex and kernel mutex.
Semaphores are used for multi-thread and multi-task synchronization. When a thread completes an action, it tells other threads through the semaphore, and other threads perform certain actions (it is blocked there when everyone is in sem_wait). The mutex is used for multi-thread and multi-task mutual exclusion. If a thread occupies a resource, other threads cannot access it until this thread unlock, and other threads can not use this resource. For example, the access to global variables is sometimes locked and unlocked when the operation is finished. Sometimes locks and semaphores are used at the same time. "
In other words, semaphores do not necessarily lock a certain resource, but a concept in the process. For example, there are two threads A _. Thread B should wait for A thread to complete a task before carrying out its own next steps. This task does not necessarily lock a certain resource, but can also perform some calculations or data processing. Thread mutex is the concept of "locking a resource". During the locking period, other threads cannot operate on the protected data. In some cases the two are interchangeable.
The difference between the two:
Scope
Semaphores: Inter-process or inter-thread (linux inter-thread only)
Mutexes: between threads
When locked
Semaphore: as long as the value of the semaphore is greater than 0, other threads can sem_wait successfully. After success, the value of the semaphore is reduced by one. If the value value is less than 0, the sem_wait blocks until the value value is increased by one after the sem_post is released. In a word, the value of the semaphore > = 0.
Mutex: as long as it is locked, no other thread can access the protected resource. If there is no lock, the resource is obtained successfully, otherwise blocking and waiting for the resource to be available. In a word, the vlaue of a thread mutex can be negative.
Multithreading
Thread is the smallest unit that runs independently in a computer, and the runtime takes up very little system resources. Compared with multi-process, multi-process has some advantages that multi-process does not have, and the most important thing is that for multi-thread, it can save more resources than multi-process.
Thread creation
In Linux, the newly created thread is not in the original process, but the system uses a system call clone (). The system copy a process that is exactly the same as the original process, and executes thread functions in this process.
In Linux, the thread is created through the function pthread_create () function:
Pthread_create ()
Int pthread_create (pthread_t * thread, const pthread_attr_t * attr,void * (* st)
Where:
Thread represents a pointer of type pthread_t
Attr is used to specify some properties of the thread
Start_routine represents a function pointer that is called by a thread
Arg represents the parameters passed to the calling function of the thread.
When the thread is created successfully, the function pthread_create () returns 0, and a value other than 0 indicates that the thread creation failed. For the properties of the thread, it is defined in the structure pthread_attr_t.
The process of thread creation is as follows:
# include # include void* thread (void* id) {pthread_t newthid; newthid = pthread_self (); printf ("this is a new thread, thread ID is% u\ n", newthid); return NULL;} int main () {int num_thread = 5 thread ID is pthreadreadt * pt = (pthread_t *) malloc (sizeof (pthread_t) * num_thread); printf ("main thread, ID is% u\ n", pthread_self ()); for (int I = 0 I if (pthread_create (& PTT [I], NULL, thread, NULL)! = 0) {printf ("thread create failed!\ n"); return 1;}} sleep (2); free (pt); return 0;}
In the above code, you use the pthread_self () function, which is used to get the thread ID of the thread. The sleep () in the main function is used to put the main process in a waiting state so that the thread finishes execution. The final execution effect is as follows:
Thread mutex lock of Linux thread mutex lock of Linux
So, how do you use arg to pass parameters to child threads? The specific implementation is as follows:
# include # include void* thread (void* id) {pthread_t newthid; newthid = pthread_self (); int num = * (int *) id; printf ("this is a new thread, thread ID is% u Ladze% d\ n", newthid, num); return NULL;} int main () {/ / pthread_t thid; int num_thread = 5; pthread_t * pt = (pthread_t *) malloc (sizeof (pthread_t) * num_thread) Int * id = (int *) malloc (sizeof (int) * num_thread); printf ("main thread, ID is% u\ n", pthread_self ()); for (int I = 0; I if (pthread_create (& PT [I], NULL, thread, & id [I])! = 0) {printf ("thread create failed!\ n"); return 1;} sleep (2); free (pt); free (id); return 0;
The final execution effect is shown in the following figure:
Thread mutex lock of Linux thread mutex lock of Linux
What happens if the main process ends early? Such as the following code:
# include # include void* thread (void* id) {pthread_t newthid; newthid = pthread_self (); int num = * (int *) id; printf ("this is a new thread, thread ID is% u Ladze% d\ n", newthid, num); sleep (2); printf ("thread% u is done!\ n", newthid); return NULL;} int main () {/ / pthread_t thid;int num_thread = 5 Pthread_t * pt = (pthread_t *) malloc (sizeof (pthread_t) * num_thread); int * id = (int *) malloc (sizeof (int) * num_thread); printf ("main thread, ID is% u\ n", pthread_self ()); for (int I = 0; I if (pthread_create (& PT [I], NULL, thread, & id [I])! = 0) {printf ("thread create failed!\ n"); return 1 }} / / sleep (2); free (pt); free (id); return 0;}
At this point, the main process ends ahead of schedule, and the process will reclaim the resources. at this time, all threads will exit execution, and the running result is as follows:
Thread mutex lock of Linux thread mutex thread of Linux hangs
In the above implementation, in order to enable the main thread to wait for each child thread to finish execution before exiting, the free () function is used. In the multithreading of Linux, the pthread_join () function can also be used to wait for other threads. The specific form of the function is:
Int pthread_join (pthread_t thread, void * * retval)
The function pthread_join () is used to wait for the end of a thread, and its call will be suspended.
A thread allows only one thread to use pthread_join () to wait for its termination.
If you need to wait for the end of each child thread in the main thread, as shown in the following code:
# include # include void* thread (void* id) {pthread_t newthid; newthid = pthread_self (); int num = * (int *) id; printf ("this is a new thread, thread ID is% uGI IDRO% d\ n", newthid, num); printf ("thread% u is done\ n", newthid); return NULL;} int main () {int num_thread = 5; pthread_t * pt = (pthread_t *) malloc (sizeof (pthread_t) * num_thread) Int * id = (int *) malloc (sizeof (int) * num_thread); printf ("main thread, ID is% u\ n", pthread_self ()); for (int I = 0; I if (pthread_create (& PT [I], NULL, thread, & id [I])! = 0) {printf ("thread create failed!\ n"); return 1;} for (int I = 0; I return 0;}
The final execution effect is as follows:
Thread mutex lock of Linux thread mutex lock of Linux
Note: when compiling, you need to link libpthread.a:
Gmail + xx.c-lpthread-o xx
Mutex mutex
The problem of multithreading is introduced.
The most important feature of multithreading is the sharing of resources. however, when multiple threads operate (change) a critical resource at the same time, it will destroy the critical resource. For example, using multithreading to write a file at the same time:
# include # include const char filename [] = "hello"; void* thread (void* id) {int num = * (int *) id; / / write file operation FILE * fp = fopen (filename, "a +"); int start = * (int *) id); int end = start + 1; setbuf (fp, NULL); / / set buffer size fprintf (stdout, "% d\ n", start); for (int I = (start * 10); I "% d\ t", I) } fprintf (fp, "\ n"); fclose (fp); return NULL;} int main () {int num_thread = 5; pthread_t * pt = (pthread_t *) malloc (sizeof (pthread_t) * num_thread); int * id = (int *) malloc (sizeof (int) * num_thread); for (int I = 0 I if (pthread_create (& PTT [I], NULL, thread, & id [I])! = 0) {printf ("thread create failed!\ n"); return 1;}} for (int I = 0; I return 0;}
Execute the above code, we will find that the result is chaotic, the main reason is that in the process of writing multithreaded code, each thread tries to write the same file, so the above problem arises, which is the synchronization problem of shared resources. In Linux programming, the processing methods of thread synchronization include semaphores, mutexes and condition variables.
Mutex lock
Mutex is to realize the synchronization between threads through the mechanism of lock. The basic flow of a mutex is:
Initialize a mutex: the pthread_mutex_init () function
Locking: pthread_mutex_lock () function or pthread_mutex_trylock () function
Operations on shared resources
Unlock: pthread_mutex_unlock () function
Log out mutex: pthread_mutex_destory () function
Among them, the process of the pthread_mutex_lock () function and the pthread_mutex_trylock () function is slightly different during the locking process:
When using the pthread_mutex_lock () function to lock, if it is already locked, the thread trying to lock will be blocked until the mutex is released by other threads. When the pthread_mutex_lock () function has a return value, the locking is successful.
When using the pthread_mutex_trylock () function to add a lock, if it is already locked at this time, the error code of EBUSY will be returned.
At the same time, in the process of unlocking, two conditions need to be met:
Mutex must be locked before unlocking
Must be unlocked by a locked thread.
When the mutex is used, it must be cleared.
With the above preparation, we re-implement the above multithreaded write operation. In fact, the code is as follows:
# include # include pthread_mutex_t mutex;const char filename [] = "hello"; void* thread (void* id) {int num = * (int *) id; / / locked if (pthread_mutex_lock (& mutex)! = 0) {fprintf (stdout, "lock error!\ n");} / / operations FILE * fp = fopen (filename, "a +"); int start = * (int *) id); int end = start + 1 Setbuf (fp, NULL); / / set the size of the buffer fprintf (stdout, "% d\ n", start); for (int I = (start * 10); I "% d\ t", I);} fprintf (fp, "\ n"); fclose (fp); / / unlock pthread_mutex_unlock (& mutex); return NULL;} int main () {int num_thread = 5 Pthread_t * pt = (pthread_t *) malloc (sizeof (pthread_t) * num_thread); int * id = (int *) malloc (sizeof (int) * num_thread); / / initialize mutex if (pthread_mutex_init (& mutex, NULL)! = 0) {/ / Mutex initialization failed free (pt); free (id); return 1;} for (int I = 0 I if (pthread_create (& PTT [I], NULL, thread, & id [I])! = 0) {printf ("thread create failed!\ n"); return 1;}} for (int I = 0; I return 0;}
The final result is:
The above is all the contents of the article "sample Analysis of Thread Mutex Lock in Linux". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.