经典进程的同步问题

经典进程的同步问题

1.生产者—消费者问题

问题:

若干进程通过有限的共享缓冲区交换数据。其中,“生产者”进程不断写入,而“消费者”进程不断读出;共享缓冲区共有N个;任何时刻只能有一个进程.可对共享缓冲区进行操作。

解决思路:

1)在访问公共缓冲区的时候,进程之间是互斥的
2)当缓冲区为空时,“消费者”进程不能读出
3)当缓冲区为满时,“生产者”进程不能写入

采用AND信号量解决问题:

semaphore  full=0;     	//满缓冲区单元个数
semaphore  empty=n;    //空缓冲区单元个数
semaphore  mutex=1;    //互斥信号量:控制对临界资源的访问
char  buffer[n];     
int  in=0,out=0; 
char nextc,nextp;


void producer()                //生产者进程
{  
do {  
produce an item nextp;    	//生产一个数据
      Swait(empty,mutex); //空缓冲区数量减1;进入临界区
      buffer[in]=nextp;        //将一个数据送入缓冲池
      in=(in+1) % n;              //修改in指针
      Ssignal(mutex , full);//退出临界区;,满缓冲区数量增1
	  }while(TRUE);
}
void consumer()                 		//消费者进程
{  
	 do{                	 
      Swait( full , mutex);  //满缓冲区数减1,进入临界区
      nextc=buffer[out];    	//从缓冲区读出一个数据
      out=(out+1) mod n;     //修改out指针
      Ssignal(mutex , empty);//退出临界区;空缓冲区数增1
      consume the item in nextc; 	//消费一个数据
	  } while(TRUE);
}


//主程序运行
void main()           
{  cobegin                //进程之间并发执行
	    producer();
      consumer();
   coend
}

2.哲学家进餐的问题

问题:

有五个哲学家公用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五支筷子,他们的生活方式是交替地进行思考和快餐,平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有他拿到两只筷子时才能进餐

解决思路:

临界资源:筷子

方法:

1)最多允许四个哲学家同时进餐
2)仅当哲学家的左、右两只筷子均可用,才允许他进餐。
3)规定奇数号哲学家先拿他左边的筷子,然后再去拿他右边的筷子;而偶数号哲学家则相反。
确认这些都不被违背,以保证至少一个哲学家能够进餐,最终释放出他所使用过的筷子,从而使得更多的哲学家进餐。

采用AND信号量解决:

semaphore chopstick[5]= {1,1,1,1,1};
do{
	think;
	swait(chopstick[(i+1)%5],chopstick[i]);//等待拿到两只筷子
	eat;
	ssginal(chopstick[(i+1)% 5],chopstick[i]);//释放两只筷子
}while(TRUE); 

3.读者-写者问题

问题:

一个数据对象(数据文件或记录),可以被多个进程共享。其中有些进程要读,有些要写或修改。
允许多个读者进程同时读一个共享对象,但不允许一个写者进程和其它读者或写者进程同时访问共享对象。

解决思路:

1)读进程和写进程之间是互斥的
2)读进程和读进程之间是非互斥的
3)写进程和写进程之间是互斥的

采用信号量集机制解决问题:

 //保证多个读,有人写的时候不能读
Reader
Swait(L,1,1 );
Swait( mx,1,0);    //有着开关的作用①
Read;
Ssignal(L,1)
//有人读时不能写,并与写互斥
Writer
Swait(mx,1,1;L,RN,0); //② 
Write;
Ssignal(mx,1)
① 只要无Write进程进入写操作,mx=1,reader进程就都可以进行读操作,若mx=0,则不可以。
②表示读进程和写进程都没有的时候,Write进程才可以进入临界区
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经典进程同步问题通常包括生产者-消费者问题、读者-写者问题和哲学家就餐问题等。这里以生产者-消费者问题为例,简单介绍一下如何在 C 语言中实现进程同步。 生产者-消费者问题是指多个进程共享同一个缓冲区,其中生产者进程向缓冲区中写入数据,而消费者进程则从缓冲区中读取数据。为了避免竞争条件和死锁等问题,需要使用同步机制来保证进程之间的协调工作。 使用信号量可以实现进程同步。信号量是一个计数器,用于控制对共享资源的访问。在 C 语言中,我们可以使用 POSIX 信号量库来创建和使用信号量。 下面是一个简单的生产者-消费者问题的代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #define BUFFER_SIZE 10 int buffer[BUFFER_SIZE]; int in = 0, out = 0; sem_t empty; // 缓冲区空闲信号量 sem_t full; // 缓冲区满信号量 pthread_mutex_t mutex; // 互斥锁 void *producer(void *arg) { int item; while (1) { item = rand() % 100; // 生产一个随机数 sem_wait(&empty); // 当缓冲区空间为 0 时等待 pthread_mutex_lock(&mutex); buffer[in] = item; in = (in + 1) % BUFFER_SIZE; // 循环缓冲区 printf("Producer produced item %d\n", item); pthread_mutex_unlock(&mutex); sem_post(&full); // 增加缓冲区中的项目数 } pthread_exit(NULL); } void *consumer(void *arg) { int item; while (1) { sem_wait(&full); // 当缓冲区中没有项目时等待 pthread_mutex_lock(&mutex); item = buffer[out]; out = (out + 1) % BUFFER_SIZE; // 循环缓冲区 printf("Consumer consumed item %d\n", item); pthread_mutex_unlock(&mutex); sem_post(&empty); // 增加缓冲区的空闲空间 } pthread_exit(NULL); } int main(int argc, char **argv) { pthread_t producer_thread, consumer_thread; sem_init(&empty, 0, BUFFER_SIZE); // 初始化信号量 sem_init(&full, 0, 0); pthread_mutex_init(&mutex, NULL); pthread_create(&producer_thread, NULL, producer, NULL); pthread_create(&consumer_thread, NULL, consumer, NULL); pthread_join(producer_thread, NULL); pthread_join(consumer_thread, NULL); sem_destroy(&empty); // 销毁信号量和互斥锁 sem_destroy(&full); pthread_mutex_destroy(&mutex); return 0; } ``` 在这个示例中,我们使用了两个信号量 `empty` 和 `full` 来控制缓冲区的空闲空间和项目数。当 `empty` 为 0 时,表示缓冲区已满,生产者需要等待;当 `full` 为 0 时,表示缓冲区没有项目,消费者需要等待。使用互斥锁 `mutex` 来保护共享资源的访问,避免竞争条件。 当生产者生成一个随机数时,将其写入缓冲区,同时增加 `in` 指针,表示缓冲区中的项目数增加了一个。当消费者读取缓冲区中的项目时,将其存储到 `item` 中,并将 `out` 指针增加,表示缓冲区中的项目数减少了一个。 上述代码中,生产者和消费者都是无限循环运行的,可以使用 `pthread_cancel()` 函数来终止它们的运行。此外,还需要注意的是,在使用信号量等同步机制时,不要忘记释放已经申请的资源,否则可能会导致死锁等问题

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值