Thread synchronization mutual exclusion mechanism (mutex lock)

1. Thread synchronization and mutual exclusion

        Critical Section: A section of code that accesses a shared resource

        Critical resources: shared resources that are read and written in the critical area, that is, resources that can only be accessed by one process at the same time

        If there is communication between threads, a synchronous mutual exclusion mechanism needs to be introduced to avoid race conditions and ensure that only one thread handles critical resources at any time

2. Mutex lock

2.1 Working principle

        For threads that want to access critical resources, before accessing, apply for a lock operation. If the lock is successful, they will enter the critical section and access the resources in the critical section until they exit the critical section and unlock the mutex. If the locking fails, the thread enters the dormant waiting stage, waiting for the mutex to be opened.

2.2 Create a mutex

Function: pthread_mutex_init 

Function: Create and initialize a mutex        

Function prototype:

#include <pthread.h>
pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER;  //创建方式一
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);  //创建方式二

parameter:

        pthread_mutex_t *mutex: storage application and initialized mutex

        pthread_mutexattr_t *mutexattr: mutex attribute, which can define whether the mutex is used for a process or a thread. You can use the pthread_mutexattr_init function to modify the mutex attribute, generally fill in NULL, which means it is used for threads

return value:

        always returns 0;

2.3 Locking

Function: pthread_mutex_lock

Function: lock, if other threads occupy the mutex, this function will block

Function prototype:

#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mutex);

parameter:

         pthread_mutex_t *mutex: Specifies the mutex to be locked

return value:

        success, return 0

        on failure, return non-zero

2.4 Unlock

Function: pthread_mutex_unlock

Function: Unlock the mutex

Function prototype:

#include <pthread.h>
int pthread_mutex_unlock(pthread_mutex_t *mutex);

parameter:

         pthread_mutex_t *mutex: Specifies the mutex to unlock

return value:

        success, return 0

        on failure, return non-zero

2.5 Destroy lock

Function: pthread_mutex_dsetroy

Function: Destroy the mutex

Function prototype:

#include <pthread.h>
int pthread_mutex_destroy(pthread_mutex_t *mutex);

parameter:

         pthread_mutex_t *mutex: Specifies the mutex to be destroyed

return value:

         success, return 0

        on failure, return non-zero

2.6 Deadlock

The reason for the deadlock: the thread that owns the resource has not unlocked the mutex, and there are often the following situations:

  1. The thread holding the mutex exited abnormally without releasing the lock resource
  2. The same thread locks a mutex repeatedly
  3. Mutex cross nesting

Sample code (creating two threads, one for printing and one for inversion)

#include <stdio.h>
#include <pthread.h>
#include <string.h>

//临界资源
char buf[] = "AAAA____BBBB";

//互斥锁变量  方式二
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void* callback1(void* arg)
{
    while(1)
    {
        /******临界区************/
        //上锁
        pthread_mutex_lock(&mutex);

        printf("%s\n", buf);

        //解锁
        pthread_mutex_unlock(&mutex);
        /******临界区************/
    }
    pthread_exit(NULL);
}


void* callback2(void* arg)
{
    char temp = 0;

    while(1)
    {
        /******临界区************/
        //上锁
        pthread_mutex_lock(&mutex);

        for(int i=0; i<strlen(buf)/2; i++)
        {
            temp = buf[i];
            buf[i] = buf[strlen(buf)-1-i];
            buf[strlen(buf)-1-i] = temp;
        }

        //解锁
        pthread_mutex_unlock(&mutex);
        /******临界区************/
    }


    pthread_exit(NULL);
}


int main(int argc, const char *argv[])
{
    /*
    //创建互斥锁:方式一
    if(pthread_mutex_init(&mutex, NULL) != 0)
    {
        fprintf(stderr, "pthread_mutex_init failed __%d__\n", __LINE__);
        return -1;
    }
    */
                                                                                                                            

    pthread_t tid1, tid2;
    //创建线程:打印
    if(pthread_create(&tid1, NULL, callback1, NULL) != 0)
    {
        fprintf(stderr, "pthread_create failed\n");
        return -1;
    }
    pthread_detach(tid1);

    //创建线程:倒置
    if(pthread_create(&tid2, NULL, callback2, NULL) != 0)
    {
        fprintf(stderr, "pthread_create failed\n");
        return -1;
    }


    pthread_join(tid2, NULL);

    //销毁互斥锁
    pthread_mutex_destroy(&mutex);

    return 0;
}

おすすめ

転載: blog.csdn.net/weixin_53478812/article/details/132111710