给多线程程序上锁以及死锁的举例

一个正常的多线程程序,为了防止多个线程在差不多一个时间里对一个数据做手脚,在每个线程上都是要上锁的。每个程序都有自己独有的一个小房间,所谓上锁,就是在它运行的时候把自己的门关紧,然后在房间里对数据们做不可描述的事情,其他程序想来对数据做手脚,不可能的,它们只有在外面等着,只有等到我处理完事情后自己把门开开,也就是所谓的解锁。

今天我们来简要分析一下互斥锁的用法,多线程的程序上次已经解释过了,这里不再废话。

函数原型:int pthread_mutex_lock(pthread_mutex_t *mutex);

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
int    g_var = 0;
pthread_mutex_t lock;          //生成一把叫lock的锁
void *thread_worker1(void *arg)
{
    while(1)
    {
        pthread_mutex_lock(&lock);        //现在开始上锁,处理数据
        printf("thread1 g_var=%d\n",++g_var);   
         pthread_mutex_unlock(&lock);       //释放锁,其他程序可以使用数据
        sleep(1);
    }
    return NULL;
}

void *thread_worker2(void *arg)
{  
     while(1)
     { 
         pthread_mutex_lock(&lock);          //同样上锁
         printf("thread2 g_var=%d\n",--g_var);         //为了观察数据变化,我将它改为-1
         pthread_mutex_unlock(&lock);           //释放锁
         sleep(1);
     }
    return NULL;
 }

int main(int argc,char **argv)
{
    pthread_t tid1;
    pthread_t tid2;

    pthread_create(&tid1,NULL,thread_worker1,"haha");
    printf("start thread_worker1[%lu]\n",tid1);

    pthread_create(&tid2,NULL,thread_worker2,"xixi");
    printf("start thread_worker2[%lu]\n",tid2);

    while(1)
    {
       printf("g_var=%d\n",++g_var);
        sleep(1);
    }

    return 0;
    
}
接下来我们看执行结果,给大家打印长一点。这样,我们可以轻松看到,每两个相邻的数据间只相差1,也就是说一个线程在操作数据的时候,其他线程都在旁观,说明我们上锁是较为成功的。
[lingyun@localhost file]$ ./a.out
start thread_worker1[3078187888]
start thread_worker2[3067698032]
g_var=1
thread2 g_var=0
thread1 g_var=1
g_var=2
thread2 g_var=1
thread1 g_var=2
g_var=3
thread2 g_var=2
thread1 g_var=3
g_var=4
thread2 g_var=3
thread1 g_var=4
g_var=5
thread2 g_var=4
thread1 g_var=5
g_var=6
thread2 g_var=5
thread1 g_var=6
g_var=7
thread2 g_var=6
thread1 g_var=7
g_var=8
thread2 g_var=7
thread1 g_var=8
g_var=9
thread2 g_var=8
thread1 g_var=9
g_var=10
thread2 g_var=9
thread1 g_var=10

最后给大家演示一下死锁,比如同一把锁在一个线程上放两次,在一个线程里敲两遍 pthread_mutex_lock(&lock),程序肯定死掉,这并非真正意义上的死锁。所谓的死锁最重要的一点是你的上锁和解锁的顺序不恰当引起的。比方说一个人要先去完厕所后去书房,而另一个人要先去完书房后去厕所,而前一个人已经进了厕所在等书房开门,而后一个人进了书房在等厕所开门,两个人都在等,无休无止地等,于是便形成了死锁。

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
int    g_var = 0;
pthread_mutex_t lock;
pthread_mutex_t suo;
void *thread_worker1(void *arg)
{
    while(1)
    {
        pthread_mutex_lock(&lock);
        sleep(1);              //已获取lock锁,等待线程2获取suo锁
        pthread_mutex_lock(&suo);
        printf("thread1 g_var=%d\n",++g_var);
        pthread_mutex_unlock(&suo);
        pthread_mutex_unlock(&lock);
        sleep(1);
    }
    return NULL;
}


void *thread_worker2(void *arg)
{  
     while(1)
     {
         pthread_mutex_lock(&suo);
         sleep(1);               //已获取suo锁,等待线程1获取lock锁
         pthread_mutex_lock(&lock);
         printf("thread2 g_var=%d\n",--g_var);
         pthread_mutex_unlock(&lock);
         pthread_mutex_unlock(&suo);
         sleep(1);
     }
    return NULL;
 }


int main(int argc,char **argv)
{
    pthread_t tid1;
    pthread_t tid2;


    pthread_create(&tid1,NULL,thread_worker1,"haha");
    printf("start thread_worker1[%lu]\n",tid1);


    pthread_create(&tid2,NULL,thread_worker2,"xixi");
    printf("start thread_worker2[%lu]\n",tid2);


    while(1)
    {
       printf("g_var=%d\n",++g_var);
        sleep(1);
    }


    return 0;
    
}
我们再看它的执行结果,就这样,线程1和线程2互相等待对方开锁,又迟迟不开自己的锁,给双方都造成麻烦,也就都无法顺利执行,剩下的就只有主程序还在孤独地自加。
[lingyun@localhost file]$ gcc lock.c -lpthread
[lingyun@localhost file]$ ./a.out             
start thread_worker1[3078122352]
start thread_worker2[3067632496]
g_var=1
g_var=2
g_var=3
g_var=4
g_var=5
g_var=6
g_var=7
g_var=8
g_var=9
g_var=10
这就好比人与人之间,俗话说得好,退一步海阔天空,互相包容体谅,才能更加长远地走下去啊。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姜亚轲

你花钱的样子真帅

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值