第十二章 并发编程

构建并发服务器的方法:在父进程中接收客户端连接请求,然后创建一个新的子进程来为每个新客户端提供服务。

假设现在有两个客户端和一个服务器,服务器正在监听一个监听描述符上的连接请求。并发过程如下:

1、服务器接受客户端1的连接请求

2、服务器派生一个子进程为这个客户端1服务

3、服务器接受另一个客户端2的连接请求

4、服务器派生另一个子进程为新的客户端2服务

 

I/O多路复用可以用做并发事件驱动程序的基础,在事件驱动程序中,某些事件会导致流向前推进,一般的思路是将逻辑流模型化为状态机。I/O多路复用来显示的调度这些流。一个状态机就是由一组状态、输入事件、转移,其中转移是将状态和输入事件映射到状态。

 

使用信号量来调度共享资源:

信号量可以用来调度对共享资源的访问。在这种场景中,一个线程用信号量操作来通知另一个线程,程序状态中的某个条件已经为真了。两个经典的例子是生产者-消费者和读者-写者问题。

生产者-消费者问题:生产者产生项目并把它们插入到一个有限的缓冲区中,消费者从缓冲区中取出这些项目,然后消费它们。

一组并发的线程要访问一个共享对象,例如一个主存中的数据结构,有些线程只读对象,而其他的线程只修改对象,修改对象的线程叫做写者,只读对象的线程叫做读者。写者必须拥有对对象的独占的访问,而读者可以和无限多个其他的读者共享对象。

读者-写者问题分两种情况:

1、读者优先。要求不让读者等待,除非已经把使用对象的权限赋予了一个写者。读者不会因为一个写者在等待而等待。

2、写者优先。要求一旦一个写者准备好可以写,它就会尽可能快的完成它的写操作。

这两种读者-写者问题可能导致饥饿,饥饿是指一个线程无期限的阻塞,无法进展。例如,如果有读者不断地到达,写者就可能无限地等待。

 

 

 

 

 

线程安全

当一个函数被多个线程反复地调用时,它会一直产生正确的结果,这个函数是线程安全的。反之,该函数是线程不安全的。

四个线程不安全函数类:

1、不保护共享变量的函数

2、保持跨越多个调用的状态的函数

3、返回指向静态变量的指针的函数

4、调用线程不安全函数的函数

 

线程安全函数:

可重入函数:当它们被多个线程调用时,不会引用任何共享数据。

 

死锁:一组线程被阻塞了,等待一个永远不可能为真的条件。

规避死锁:

给定所有互斥操作的一个全序,如果每个线程都是以一种顺序获得互斥锁并以相反的顺序释放,那么这个程序就是无死锁的。

 

posted @ 2019-01-27 15:53  凌晨六点半  阅读(204)  评论(1编辑  收藏  举报