多线程编程:线程死锁的原因以及解决方法
多线程编程:线程死锁的原因以及解决方法
关于线程死锁这个问题相信程序员在编写多线程程序时会经常遇到的一个经典问题,这种情况往往出现在多个线程同时对临界资源访问时所产生的。
属于临界资源的硬件有打印机、磁带机等,软件有消息缓冲队列、变量、数组、缓冲区等。诸进程间应采取互斥方式,实现对这种资源的共享。
当我们在使用两个不同的线程访问同一个临界资源时就会出现如下情况:
线程A优先被创建出来并优先去获得对临界资源的操作权限,线程A里有一个循环代码会循环对该临界资源进行操作,因此就会操作系统内核在进程里的线程之间调度时会出现这样一种情况:线程A在对该临界资源操作时,线程B呼唤操作系统取的CPU控制权时,会有一个线程调用之间的现场保护,会对线程里的代码执行到了哪一步或者循环次数的记录保存到寄存器里,下次获取CPU控制权时会读取该记录,此时如果线程A没有结束的情况下会一直占用着该临界资源,导致线程B无法对该临界资源做写操作,从而进入无限的阻塞等待,从而导致了死锁的情况!
解决办法“加锁”:
void data_process1()
{
EnterCriticalSection(&ss1); // 申请锁的顺序有依赖
EnterCriticalSection(&ss2);
do_something1();
LeaveCriticalSection(&ss2);
LeaveCriticalSection(&ss1);
}
void data_process2()
{
EnterCriticalSection(&ss2); // 申请锁的顺序有依赖
EnterCriticalSection(&ss1);
do_something2();
LeaveCriticalSection(&ss1);
LeaveCriticalSection(&ss2);
}
当我们线程A加锁时线程B不会工作阻塞等待着线程A释放锁,这样就可以有效的防止线程B进入死锁,注意死锁的时候线程B会不断的对该临界资源写数据但是每次都会失败,而加锁的话线程B则阻塞等待着线程解锁不会做过多的额外工作!
当对硬件资源访问时也是如此,一个硬件资源同时只能被一个进程/线程所使用。