《深入理解计算机系统》读书笔记8--- 并发编程2

来源:互联网 发布:json格式怎么打开mac 编辑:程序博客网 时间:2024/06/13 01:50

接下来的内容主要就是线程的安全性问题,分别为线程同步错误,死锁和竞争。

参考了文章:http://www.cnblogs.com/Jessy/p/3540724.html

(1)同步错误

不同的线程对于共享变量的同时操作,使得最终结果出错。

一个简单的栗子,计数。

各个线程每完成一个任务,就对完成任务数+1.

到某一时刻,完成任务数累积到了5,这个时候A线程完成了任务,对任务数加1,但是这个操作是需要时间的嘛,

假若就在A还没有将任务数改为6的时候,B也完成了任务,那么B就会去取得任务数的值5,对它加1。

然后A将任务数更新为6,B也会将任务数更新为6。而实际上完成任务数是7了。


解决办法——控制对于大家都能访问的共享变量,同一时刻只能一个线程对其进行操作。

刚刚那个栗子,假若A对任务数读取的时候,其他线程就不能读取了,这样就不会出现同步出错。


具体实现——信号量(semaphore)

信号量sem是一个特殊的变量,对于它有P,V两种操作。

具体见书P668。

而对于提供互斥为目的的二元信号量,又叫作互斥锁(mutex)

那么每次操作共享变量的时候对其加锁,再解锁,便可以避免同步错误。

vlolatile int cnt =  0;

sem_t mutex;

Sem_init(&mutex, 0, 1);

{

P(&mutex);

cnt++;

V(&mutex);

}


(2)竞争

当一个程序的正确性依赖于一个线程要在另一个线程到达y点之前到达它的控制流中的x点时,就会发生竞争。

为了消除竞争,可以动态地为每个整数ID分配一个独立的块,并且传递给线程运行函数一个指向这个块的指针。


(3)死锁

死锁的概念参考这个帖子,里面对于死锁的必要条件,写的很好。

http://www.cnblogs.com/Jessy/p/3540724.html

互斥条件:

(1)一个资源每次只能被一个进程使用。 .

(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。

(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。

(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

解决办法:

针对二元信号量实现互斥。

如果对于程序中每对互斥锁(s,t),给所有的锁分配一个全序,每个线程按照这个顺序来请求锁,并按照逆序来释放,那么这个程序就是无死锁的。


0 0