Skip to content

信号量与互斥量

信号量与互斥量的区别

如果涉及到多线程对同一个资源进行访问,比如一个全局变量,那么就使用mutex。

如果涉及到多个线程同步问题就用信号量semaphore。

很多人闹不清楚互斥锁和信号量的区别,觉得二者都是对资源加锁的操作,其实二者真正的区别是互斥量是实现一个原子操作,也就是避免不同线程同时访问一个共享资源,导致出现异常;而信号量则是为了线程同步所设计的。

互斥量

mutex mtx;
void add(int& i) 
{
    mtx.lock();
    i++;
    mtx.unlock();
}
void sub(int& i) 
{
    mtx.lock();
    i--;
    mtx.unlock();
}
int main()
{
    int i=100;
    thread th1 (add,i);
    thread th2 (add,i);
    th1.join();
    th2.join();
    cout<<i<<endl;//应该是等于0的;
    return 0;
}

信号量

int a, b, c;
void geta()
{
    a = 1;
    semaphore_post();
}
void getb()
{
    b = 2;
    semaphore_post();
}
void getc()
{
    semaphore_wait();
    semaphore_wait();
    c = a + b;
}
t1 = thread_create(geta);
t2 = thread_create(getb);
t3 = thread_create(getc);
thread_join(t3);
//Wait:线程等待信号量,如果值大于0,则获得,值减一;如果只等于0,则一直线程进入睡眠状态,知道信号量值大于0或者超时。
//Post:执行释放信号量,则值加一;如果此时有正在等待的线程,则唤醒该线程。

可以看出信号量是用来线程间同步用的,当信号量是二进制信号量的时候,也能用来充当mutex,但是强烈建议不要这么使用,比如下面这个也能起到线程互斥的效果,但是按设计初衷来使用最好最安全。

sem = 0;
int i = 0;
void add(int& i) 
{
    sem.wait();
    i++;
}
void sub(int& i) 
{
    i--;
    sem.post();
}

Reference

https://blog.csdn.net/feng__shuai/article/details/108531439