Function and operation of mutex
mutex
Mutex is a solution to the conflict caused by multiple threads operating on shared resources at the same time when multiple threads access shared resources. When executing, which thread holds the mutex and locks the shared resources before operating on shared resources. At this time, other threads cannot operate on shared resources. Only after the thread holding the lock unlocks and releases the lock can other threads rob and lock.
Its main function is to solve the problem of multi-threaded competition for shared resources.
pthread_mutex_init mutex initialization
Prototype:
int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
Parameters:
Mutex: mutex variable address (mutex resource)
attr: attribute information
return:
Success: 1
Failed: errorr (error number)
pthread_mutex_lock lock
Prototype:
int pthread_mutex_lock(pthread_mutex_t *mutex);
Parameters:
Mutex: mutex variable address (mutex resource)
return:
Success: 1
Failed: errorr (error number)
pthread_mutex_unlock unlock
Prototype:
int pthread_mutex_unlock(pthread_mutex_t *mutex);
Parameters:
Mutex: mutex variable address (mutex resource)
return:
Success: 1
Failed: errorr (error number)
pthread_mutex_destroy destroy mutex
Prototype:
int pthread_mutex_unlock(pthread_mutex_t *mutex);
Parameters:
Mutex: mutex variable address (mutex resource)
return:
Success: 1
Failed: errorr (error number)
#include <stdio.h> #include <pthread.h> #include <unistd.h> pthread_mutex_t mutex; //Define a lock resource variable (parameter transfer is prone to problems) void *func(void *arg); int main(int argc, char **argv) { int status = pthread_mutex_init(&mutex,NULL); //Initialize mutex pthread_t thread; pthread_create (&thread, NULL,func,NULL);//Create thread while(1) //Cyclic locking { int i = 0; pthread_mutex_lock(&mutex);//Lock printf("11111 I locked it\n"); while(1) { i++; if(i == 200) { printf("i = %d\n",i); printf("11111 I unlocked it\n"); pthread_mutex_unlock(&mutex); //Unlock break; } } sleep(1); //Prevent locking immediately after unlocking } return 0; } void *func(void *arg) { pthread_t id = pthread_self(); //Get current thread id pthread_detach(id); //Set self separation while(1) //Cyclic locking { int k = 0; pthread_mutex_lock(&mutex);//Lock printf("22222 I locked it\n"); while(1) { k++; if(k == 200) { printf("k = %d\n",k); printf("22222 I unlocked it\n"); pthread_mutex_unlock(&mutex); //Unlock break; } } sleep(1); } }
deadlock
Causes of deadlock
Deadlocks can occur when a process needs exclusive access to resources. Deadlock is a deadlock caused by two or more processes competing for critical resources, that is, a process waits for a resource that has been occupied and will never be released. Without external forces, these processes cannot move forward.
Four conditions for deadlock generation
mutual exclusion
The resources involved are not shared, that is, only one process can use them at a time. If another process requests the resource, the requesting process must wait until the resource is released.
Conditions of non deprivation (non preemption)
The resources obtained by a process cannot be forcibly taken away by other processes before they are used up, that is, they can only be released by the process that obtains the resources.
Occupy and wait (partial distribution)
A process requests a portion of its resources at a time. While waiting for a new resource, the process continues to occupy the allocated resources.
Loop condition (cycle wait)
There is a circular chain with process endings. Each process in the chain is waiting for the resources held by the next process, resulting in this group of processes in a permanent waiting state.
These four conditions are necessary for deadlock. As long as the system deadlock occurs, these conditions must be true. Conversely, as long as one of the above conditions is not satisfied, deadlock will not occur. Therefore, to avoid deadlock, you only need to break its necessary conditions.
Deadlock prevention in threads
pthread_cleanup_push stack thread processing function
Prototype:
void pthread_cleanup_push(void (*routine)(void *), void *arg)
function
Function stack (thread cleanup function)
Parameters:
routine: canceling function of thread
arg: parameter of the thread's cancel handler
pthread_cleanup_pop stack pressing thread processing function
Prototype:
void pthread_cleanup_pop(int execute)
function
This function calls pthread when the program terminates abnormally_ cleanup_ Push() is pushed into the cleaning function stack, which is managed by the first in then out stack structure
Parameters:
execute:
Write 0: cancel the stack thread processing function, but do not execute the function
Non 0: cancel the processing function of the pop-up stack thread and execute the function
This parameter does not affect the execution of the cleanup function upon abnormal termination
Sample code
#include <stdio.h> #include <pthread.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <string.h> //Define mutex pthread_mutex_t mutex; void *routine(void *arg); void function(void *arg); int main() { pthread_mutex_init(&mutex, NULL);//Initialize mutex pthread_t id;//Define a thread ID number pthread_create(&id, NULL, routine, NULL);//Create thread -- save address of thread id number while(1) //Cyclic locking { pthread_mutex_lock(&mutex); //Lock printf("1 I locked it!!\n"); char buf[128]; while(1) { printf("Thread 1:"); scanf("%s", buf); if(!strcmp(buf,"A")) { break; } } printf("1 I unlocked!!\n"); pthread_mutex_unlock(&mutex);//Unlock sleep(1); } pthread_mutex_destroy(&mutex);//Destroy mutex pthread_exit(NULL); } //Thread function void *routine(void *arg) { pthread_t id = pthread_self(); while(1) { pthread_mutex_lock(&mutex);//Lock pthread_cleanup_push(function,NULL); //Function stack (thread cleanup function) printf("2 I locked it!!\n"); char buf[128]; while(1) { printf("Thread 2:"); scanf("%s", buf); if(!strcmp(buf,"B")) { break; } if(!strcmp(buf,"Z")) { pthread_cancel(id); //Cancel thread } } printf("2 I unlocked!!\n"); pthread_mutex_unlock(&mutex); //Unlock pthread_cleanup_pop(0); //Normal exit does not execute thread cleanup function sleep(1); } return NULL; } //Cleanup function (deadlock prevention) void function(void *arg) { printf("Yo, what's the matter\n"); //Unlock (prevent deadlock caused by abnormal thread termination) pthread_mutex_unlock(&mutex); }