linux线程同步的互斥锁(mutex)到底怎么用的》?谢谢

linux线程同步的互斥锁(mutex)到底怎么用的》?谢谢,第1张

互斥锁(mutex) 通过锁机制实现线程间的同步。

1、初始化锁。在Linux下,线程的互斥量数据类型是pthread_mutex_t。在使用前,要对它进行初始化。

2、静态分配:pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER

3、动态分配:int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutex_attr_t *mutexattr)

4、加锁。对共享资源的访问,要对互斥量进行加锁,如果互斥量已经上了锁,调用线程会阻塞,直到互斥量被解锁

    int pthread_mutex_lock(pthread_mutex *mutex)

    int pthread_mutex_trylock(pthread_mutex_t *mutex)

    解锁。在完成了对共享资源的访问后,要对互斥量进行解锁。

    int pthread_mutex_unlock(pthread_mutex_t *mutex)

    销毁锁。锁在是使用完成后,需要进行销毁以释放资源。

    int pthread_mutex_destroy(pthread_mutex *mutex)

    #include <cstdio>  

    #include <cstdlib>  

    #include <unistd.h>  

    #include <pthread.h>  

    #include "iostream"  

    using namespace std  

    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER  

    int tmp  

    void* thread(void *arg)  

    {  

        cout << "thread id is " << pthread_self() << endl  

        pthread_mutex_lock(&mutex)  

        tmp = 12  

        cout << "Now a is " << tmp << endl  

        pthread_mutex_unlock(&mutex)  

        return NULL  

    }  

    int main()  

    {  

        pthread_t id  

        cout << "main thread id is " << pthread_self() << endl  

        tmp = 3  

        cout << "In main func tmp = " << tmp << endl  

        if (!pthread_create(&id, NULL, thread, NULL))  

        {  

            cout << "Create thread success!" << endl  

        }  

        else  

        {  

            cout << "Create thread failed!" << endl  

        }  

        pthread_join(id, NULL)  

        pthread_mutex_destroy(&mutex)  

        return 0  

    }  

    //编译:g++ -o thread testthread.cpp -lpthread

Linux系统中,实现线程同步的方式大致分为六种,其中包括:互斥锁、自旋锁、信号量、条件变量、读写锁、屏障。最常用的线程同步方式就是互斥锁、自旋锁、信号量:

1、互斥锁

互斥锁本质就是一个特殊的全局变量,拥有lock和unlock两种状态,unlock的互斥锁可以由某个线程获得,当互斥锁由某个线程持有后,这个互斥锁会锁上变成lock状态,此后只有该线程有权力打开该锁,其他想要获得该互斥锁的线程都会阻塞,直到互斥锁被解锁。

互斥锁的类型:

①普通锁:互斥锁默认类型。当一个线程对一个普通锁加锁以后,其余请求该锁的线程将形成一个等待队列,并在锁解锁后按照优先级获得它,这种锁类型保证了资源分配的公平性。一个线程如果对一个已经加锁的普通锁再次加锁,将引发死锁对一个已经被其他线程加锁的普通锁解锁,或者对一个已经解锁的普通锁再次解锁,将导致不可预期的后果。

②检错锁:一个线程如果对一个已经加锁的检错锁再次加锁,则加锁 *** 作返回EDEADLK对一个已经被其他线程加锁的检错锁解锁或者对一个已经解锁的检错锁再次解锁,则解锁 *** 作返回EPERM。

③嵌套锁:该锁允许一个线程在释放锁之前多次对它加锁而不发生死锁其他线程要获得这个锁,则当前锁的拥有者必须执行多次解锁 *** 作对一个已经被其他线程加锁的嵌套锁解锁,或者对一个已经解锁的嵌套锁再次解锁,则解锁 *** 作返回EPERM。

④默认锁:一个线程如果对一个已经解锁的默认锁再次加锁,或者对一个已经被其他线程加锁的默认锁解锁,或者对一个解锁的默认锁解锁,将导致不可预期的后果这种锁实现的时候可能被映射成上述三种锁之一。

【老男孩教育】Linux运维云计算课程汇集了虚拟化、云计算、安全攻防、Python开发、SRE等技术,课堂效率高、内容丰富全面,由浅入深,循序渐进,帮助学员稳扎稳打,夯实基础,在有限的时间内帮助学员高效提升,成为符合企业需求的技术型人才。

2、自旋锁

自旋锁顾名思义就是一个死循环,不停的轮询,当一个线程未获得自旋锁时,不会像互斥锁一样进入阻塞休眠状态,而是不停的轮询获取锁,如果自旋锁能够很快被释放,那么性能就会很高,如果自旋锁长时间不能够被释放,甚至里面还有大量的IO阻塞,就会导致其他获取锁的线程一直空轮询,导致CPU使用率达到100%,特别CPU时间。

3、信号量

信号量是一个计数器,用于控制访问有限共享资源的线程数。


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7127257.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-01
下一篇 2023-04-01

发表评论

登录后才能评论

评论列表(0条)

保存