1 2 3 4

CSAPP(第三版)第十二章并发编程学习笔记

基于进程的并发编程

构造并发程序最简单的方法就是用进程。

基于进程的并发服务器

下图展示了一个基于进程的并发echo服务器代码。
image

进程的优劣

对于在父,子进程间共享状态信息,进程有一个非常清晰的模型:共享文件表,但是不共享用户地址空间。。进程有独立的地址空间既是优点也是缺点。

基于I/O多路复用的并发编程

假设要求你编写一个echo服务器,它也能对用户从标准输入键入的交互命令做出响应。在这种情况下,服务器必须响应两个互相独立的I/O事件:1.网络客户端发起连接请求,2.用户在键盘上键入命令行。如果在accept中等待一个连接请求,我们就不能响应输入的命令。类似的,如果在read中等待一个输入命令,我们就不能响应任何连接请求。

基于I/O多路复用的并发事件驱动服务器

I/O多路复用可以用作并发事件驱动程序的基础,在事件驱动程序中,某些事件会导致向前推进。一般的思路是将逻辑模型化为状态机。不严格的说,一个状态就就是一组状态,输入事件和转移,其中转移是将状态和输入事件映射到状态。每个状态是将一个(输入状态,输出事件)对映射到一个输出状态。

I/O多路复用技术的优劣

基于线程的并发编程

线程就是运行在进程上下文中的逻辑流。在本书迄今为止,程序都是由每个进程中一个线程组成的。

线程执行模型

image

Posix线程

Posix线程是在C程序中处理线程的一个标准接口。它最早出现在1995年,而且在所有的Linux系统上都可用。

创建线程

线程通过调用pthread_create函数来创建其他线程。
image

终止线程

一个线程是以下列方式之一来终止的:

  • 当顶层的线程例程返回时,线程会隐式地终止。
  • 通过调用pthread_exit函数,线程会显式的终止。
  • 某个对等线程调用Linux的exit函数,该函数终止进程以及所有与该进程相关的线程。
  • 另一个对等线程通过以当前线程ID座位参数调用pthread_cancel函数来终止当前线程。

回收已终止线程的资源

线程通过嗲用pthread_join函数等待其他线程终止。pthread_jion函数会阻塞,直到线程tid终止,将线程例程返回的通用指针赋值为thread_return指向的位置,然后回收已终止线程占用的所有内存资源。

分离线程

在任何一个时间点上,线程是可结合的或者可分离的。

初始化线程

pthread_once函数允许你初始化与线程例程相关的状态。

多线程程序中的共享变量

线程的基础内存模型是什么,
根据这个模型,变量实例是如何映射到内存的,
有多少线程引用这些实例

线程内存模型

一组并发线程运行在一个进程的上下文中。每个线程都有它独立的线程上下文,包括线程ID,栈,栈指针,程序计数器,条件码和通用目的寄存器。每个线程和其他线程一起共享进程上下文的剩余部分。这包括整个用户虚拟地址空间,它是由只读文本,读/写数据,堆以及所有的共享库代码和数据区域组成的。线程也共享相同的打开文件的集合。

将变量映射到内存

  • 全局变量:全局变量是定义在函数之外的变量,在运行时,虚拟内存的读/写区域只包含每个全局变量的一个实例。
  • 本地自动变量:本地自动变量就是定义在函数内部但是没有static属性的变量。运行时,每个线程的栈都包含它自己的所有本地自动变量的实例。
  • 本地静态变量:本地静态变量是定义在函数内部并有static属性的变量。和全局变量一样,虚拟内存的读/写值包含在程序中声明的每个本地静态变量的一个实例。

共享变量

我们说一个变量v是共享的,当且仅当它的一个实例呗一个以上的线程引用。

用信号量同步线程

共享变量是十分方便,但是它们的也引入了同步错误的可能性。
image
image

进度图

进度图将n个并发线程的执行模型化为一条n维笛卡儿空间中的轨迹线。
image

信号量

Edsger Dijkstra,并发编程领域的先锋人物,提出了一种经典的解决同步不同执行线程的方法,这种方法是基于一种叫做信号量的特殊变量的。信号量s是具有非负整数值的全局变量,只能由两种特殊的操作来处理,这两种操作称为P和V:

  • P(s):如果S是非零的,那么P将s减1,并且立即返回。如果s为零,那么就挂起这个县城,知道s变为非零,而一个V操作会重启这个线程。在重启之后,P操作将s减1,并将控制返回给调用者。
  • V(s):V操作将s加1.如果有任何线程阻塞在P操作等待s变成非零,那么V操作会重启这些线程中的一个,然后改线程将s减1,完成它的P操作。

使用信号量来实现互斥

信号量提供了一种很方便的方法来确保对共享变量的互斥访问。基本思想是将每个共享变量与一个信号量联系起来,然后用P(s)和V(s)操作将相应的临界区包围起来。

利用信号量来调度共享资源

信号量的另一个重要作用是调度对共享资源的访问。

posted @ 2022-11-15 10:09  无序  阅读(55)  评论(0编辑  收藏  举报