OS回顾---进程同步

进程同步是指在多道程序的环境下,存在着不同的制约关系,为了协调这种相互制约的关系,实现资源共享和进程协作,从而避免进程之间的冲突,进而引入进程同步。

临界资源

对于某些资源来说,在同一时间只能被一个进程所占用,这些资源就被成为临界资源。典型的临界资源比如物理上的打印机等等。

对于临界资源的访问,必须是互斥的,也就是当临界资源被占用时,另一个申请临界资源的进程会被阻塞,直到其所申请的临界资源被释放。进程内访问临界资源的代码被称为临界区。

进程同步

指为了完成某任务而建立的两个或多个线程,这些线程需要在某些位置上协调他们的工作而等待、传递信息所产生的制约关系。

比如B进程需要A进程执行完毕才能执行,所以为了等待A进程,B进程就先会阻塞,等A进程执行完毕之后才会去执行。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k09jxWW4-1615636902447)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/6b0ee893-ac6f-4763-b673-fb603ddb26ea/0603E3BA-6A21-4BC8-93D2-CD58C6625191.jpeg)]

进程互斥

某个进程进入临界区后,另外一个想要进入临界区的进程必须等待,只有当临界区中的进程退出临界区后,等待的进程才可以进入临界区。

实现临界区互斥的方法

信号量

也就是PV操作。设置一个表示资源个数的信号量S,通过对S的P、V操作来实现进程的互斥。

P也就是占有,也就是对S进行减操作,表示有一个进程将占有或者等待资源,如果S≥0则继续,否则将进程阻塞,并放入阻塞队列。

V也就是释放,也就是对S进行加操作,表示有一个占用资源的进程释放了资源,如果S≤0则会从阻塞队列中唤醒一个进程来执行。

信号量和互斥量的区别

  • 信号量:多线程同步使用的;一个线程完成某个动作后通过信号告诉别的线程,别的线程才可以执行某些动作;
  • 互斥量:多线程互斥使用的;一个线程占用某个资源,那么别的线程就无法访问,直到该线程离开,其他线程才可以访问该资源;

生产者消费者问题

需要三个信号量:empty(空资源)、full(满资源)、mut(互斥)

生产者生产资源时,就P(empty) V(full),并且在进入临界区时P(mut)出来时V(mut)。

消费者消费资源时,就P(full) V(empty),并且在进入临界区时P(mut)出来时V(mut)。

哲学家就餐

哲学家只需要一个信号量,但是他的核心在于他对筷子的控制。当有5位哲学家时:

/*当哲学家饥饿时,总是先拿左边的筷子,再拿右边的筷子*/
// P操作
wait(chopstick[i]);
wait(chopstick[(i+1)%5]);
// 吃饭
/*当哲学家进餐完成后,总是先放下左边的筷子,再放下右边的筷子*/
// V操作
signal(chopstick[i]);
signal(chopstick[(i+1)%5]);

读者写着问题

读者和写者之间互斥信号量wrMutex,代表读者个数的信号量信号量readCount,以及保护readCount的互斥信号量rMutex。

互斥信号量wrt,初值是1,代表一个共享文件,解决“读-写”互斥,“写-写”互斥。

一个记数器,即整型变量readcount,记录读者数,初值是0。 来一个读者, readcount加1 当readcount =1表示是第一个读者, 则需要执行p操作抢占文件;否则表示已有读者在安全的读数据。 走一个读者,readcount减1 当readcount =0表示是最后一个读者,则需要v操作释放资源;否则表示还有读者在读数据。

所以对于读者来说,开始读之前,得让readCount加一,并且这段操作需要使用到rMutex互斥信号量;读完之后也得让readCount—,这段操作也得需要rMutex互斥信号量。中间的操作需要用到wrMutex,先P再V。

写者,直接先P再V

int readcount=0; 
semaphore mutex=1, wrt=1 ; 
 
读者进程:
        wait (mutex);
	readcount++;	
	if (readcount == 1)
	       wait(wrt);
	signal (mutex);
		…
	   reading is performed
		 …
	wait (mutex);
	readcount--;
	if (readcount == 0)
		signal (wrt);
	signal (mutex);
 
 
写者进程:     
      wait(wrt);
	    …
         writing is performed
	    …
      signal(wrt);

银行家算法

当一个进程申请使用资源的时候,银行家算法通过先 试探 分配给该进程资源,然后通过安全性算法判断分配后的系统是否处于安全状态,若不安全则试探分配作废,让该进程继续等待。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AXXPGOn0-1615636902448)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/52877484-62dd-49b3-b7a1-4f7b6dff6634/Untitled.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o3fYkMl1-1615636902452)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/1a848e2c-3b36-47e3-b34c-439ff3d07551/Untitled.png)]

线程同步的方式主要有: 临界区(Critical Section)、互斥量(Mutex)、信号量(Semaphore)、事件(Event)。

他们的主要区别和特点如下:

**1)临界区:**通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。在任意时刻只允许一个线程对共享资源进行访问,

如果有多个线程试图访问公共资源,那么在有一个线程进入后,其他试图访问公共资源的线程将被挂起,并一直等到进入临界区的线程离开,临界区在被释放后,其他线程才可以抢占。

**2)互斥量:**采用互斥对象机制。 只有拥有互斥对象的线程才有访问公共资源的权限,因为互斥对象只有一个,所以能保证公共资源不会同时被多个线程访问。

互斥不仅能实现同一应用程序的公共资源安全共享,还能实现不同应用程序的公共资源安全共享。

**3)信号量:**它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。

4)事 件: 通过通知操作的方式来保持线程的同步,还可以方便实现对多个线程的优先级比较的操作。

猜你喜欢

转载自blog.csdn.net/why1092576787/article/details/114760455