>시스템 튜토리얼 >리눅스 >Linux 다중 스레드 뮤텍스: 스레드로부터 안전한 동기화 메커니즘

Linux 다중 스레드 뮤텍스: 스레드로부터 안전한 동기화 메커니즘

PHPz
PHPz앞으로
2024-02-13 13:40:17488검색

Linux 시스템은 다중 작업의 동시 실행을 지원하는 운영 체제로, 동시에 여러 프로세스를 실행할 수 있어 시스템 활용도와 효율성이 향상됩니다. 그러나 프로세스에 여러 스레드가 있고 이러한 스레드가 일부 데이터나 리소스를 공유해야 하는 경우 데이터 불일치 또는 리소스 경쟁이 발생하여 시스템 오류나 예외가 발생할 수 있습니다. 이 문제를 해결하려면 세마포어, 조건 변수, 뮤텍스 등과 같은 일부 동기화 메커니즘을 사용해야 합니다. 그 중 뮤텍스는 비교적 간단하고 효과적인 동기화 메커니즘으로, 스레드가 공유 데이터나 리소스에 액세스할 때 이를 잠그어 다른 스레드가 동시에 액세스하지 못하도록 하여 스레드 안전성을 보장합니다. 이 기사에서는 뮤텍스의 초기화, 잠금, 잠금 해제 및 파괴를 포함하여 Linux 시스템에서 다중 스레드 뮤텍스의 상호 배제 방법을 소개합니다.

동기화

동일한 프로세스의 여러 스레드는 프로세스의 메모리 리소스를 공유합니다. 여러 스레드가 동시에 동일한 공유 리소스에 액세스하는 경우 데이터 불일치 및 덮어쓰기와 같은 문제를 피하기 위해 서로 조정해야 합니다. 및 통신을 스레드 동기화 문제라고 합니다. 스레드 동기화의 개념은 여러 스레드가 공유 리소스에 병렬이 아닌 순차적으로 액세스할 수 있도록 하는 것입니다

상호 배제 VS 동기화

  • 상호 배제: 특정 리소스가 동시에 한 명의 방문자만 액세스할 수 있도록 허용하며 고유하고 배타적임을 의미합니다. 그러나 상호 배제는 방문자가 리소스에 액세스하는 순서를 제한할 수 없습니다. 즉, 액세스에는 순서가 없습니다. 연산이 원자적 연산이라면 당연히 상호 배타적입니다
  • 동기화: (대부분의 경우) 상호 배제를 기반으로 다른 메커니즘을 통해 방문자가 자원에 질서 있게 접근하는 것을 의미합니다. 대부분의 경우 동기화는 이미 상호 배제를 구현하며, 특히 리소스에 대한 모든 쓰기가 상호 배타적이어야 하는 경우에는 더욱 그렇습니다. 어떤 경우에는 여러 방문자가 동시에 리소스에 액세스하도록 허용될 수 있습니다

뮤텍스:

  • 본질적으로 리소스에 대한 독점 액세스를 제공하는 잠금이므로 Mutex의 주요 기능은 상호 배제입니다. 뮤텍스는 동시에 하나의 스레드만 데이터에 액세스하도록 허용하며 0/1 세마포로 간주될 수 있습니다
  • Mutex 객체의 값은 0과 1뿐입니다. Mutex의 잠금 상태와 유휴 상태를 각각 나타냅니다.
    • 잠금 상태: 현재 개체가 잠겨 있습니다. 사용자 프로세스/스레드가 중요한 리소스를 잠그려고 하면 대기 상태가 됩니다. Idle 상태: 현재 개체가 유휴 상태이고 사용자 프로세스/스레드가 중요한 리소스를 잠글 수 있으며 이후 Mutex 값이 1씩 감소하여 0이 됩니다.
    Mutex는 생성될 때 초기 값을 가질 수 있으며, 이는 Mutex가 생성된 후 잠긴 상태인지 유휴 상태인지를 나타냅니다.
  • 동일한 스레드에서 교착 상태를 방지하기 위해 시스템은 Mutex가 연속으로 두 번 잠기는 것을 허용하지 않습니다(시스템은 일반적으로 두 번째 호출 후 즉시 반환됩니다). 즉, 잠금 및 잠금 해제라는 두 가지 해당 작업이 동일한 스레드에서 완료되어야 합니다.
Mutex 모델

으아악

교착상태

Deadlock은 주로 여러 개의 종속 잠금이 있을 때 발생하며, 한 스레드가 다른 스레드와 반대 순서로 뮤텍스를 잠그려고 할 때 발생합니다

black ball
스레드가 A-> 방향으로 공유 리소스를 사용하고, 흰색 공 스레드가 B->A 순서로 공유 리소스를 사용하는 경우, 안타깝게도 black ball 스레드는 A 리소스를 다음까지 잠급니다. 릴리스된 B 리소스를 획득하고, 흰색 볼 스레드는 릴리스된 리소스 A를 얻을 때까지 리소스 B를 잠급니다. 최종 결과는 그들이 원하는 리소스를 얻을 수 없고 상대방이 원하는 리소스를 모두 잠그는 것입니다

解决死锁:

  • 对共享资源操作前一定要获得锁
  • 完成操作后一定要释放锁
  • 尽量短的时间占用锁
  • 如果有多锁,如获得的顺序是ABC顺序,那么释放顺序也该是ABC
  • 线程错误返回时会释放它所获得的锁

例子

#include
#include
#include
#include

char* buf[5];
int pos;
//1.定义互斥量
pthread_mutex_t mutex;
void* task(void* pv){
    //3.使用互斥量进行加锁
    pthread_mutex_lock(&mutex);
    
    //4.访问共享内存
    buf[pos]=(char*)pv;
    sleep(1);
    pos++;

    //5.使用互斥量进行解锁
    pthread_mutex_unlock(&mutex);
}
main(){
    //2.初始化互斥量
    pthread_mutex_init(&mutex,NULL);

    pthread_t thread;
    pthread_create(&thread,NULL,task,(void*)"zhangfei");
    pthread_t thread2;
    pthread_create(&thread2,NULL,task,(void*)"guanyu");
    
    pthread_join(thread,NULL);
    pthread_join(thread2,NULL);

    //打印字符指针数组中的有效数据
    int i=0;
    for(i=0;iprintf("%s ",buf[i]);
    }
    printf("\n");
    //6.如果不再使用则销毁互斥量
    pthread_mutex_destroy(&mutex);
    return 0;
}

本文介绍了Linux系统中多线程互斥量的互斥的方法,包括互斥量的初始化、加锁、解锁和销毁等方面。通过了解和掌握这些知识,我们可以更好地使用互斥量来实现多线程之间的同步,提高系统的稳定性和效率。当然,Linux系统中多线程互斥量还有很多其他的特性和用法,需要我们不断地学习和研究。希望本文能给你带来一些启发和帮助。

위 내용은 Linux 다중 스레드 뮤텍스: 스레드로부터 안전한 동기화 메커니즘의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 lxlinux.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제