信号量(上)实验

实验1:解决订票终端的临界区管理
订票终端是解决冲突问题,所以信号量的值是1
信号量(上)实验_第1张图片

#include 
#include 
#include 
#include 
int ticketAmout = 2;
// 票的数量: 全局变量
sem_t mutex;
// 定义信号量mutex
void* ticketAgent(void*
 arg){

sem_wait(&mutex);
// 执行P操作
int t = ticketAmout;
if (t > 0){
printf("One ticket sold\n");
t--;
}else{
printf("Ticket sold out\n");
}
ticketAmout = t;
sem_post(&mutex);
// 执行V操作
pthread_exit(0);
}
int main(int
 argc, char const*
 agrv[]){
pthread_t ticketAgent_tid[2];
sem_init(&mutex, 0, 1);
// 初始化信号量
for(int i = 0; i < 2; i++){
pthread_create(ticketAgent_tid+i, NULL, ticketAgent, NULL);
}
for (int i = 0; i < 2; i++){
pthread_join(ticketAgent_tid[i], NULL);
}
sleep(1);
printf("The left ticket is %d\n", ticketAmout);
sem_destroy(&mutex);
// 销毁信号量
return 0;
}

信号量(上)实验_第2张图片
不进行V操作,造成死锁
信号量(上)实验_第3张图片

第二个进程无限busy waiting。

信号量(上)实验_第4张图片

实验2:一般信号量观察
我们现在有5个线程,但是只有两份资源可用;我们通过信号量去模拟这一种情况,将信号量的值初始化为2

我们先来看一种情况,当没有信号量进行控制的时候

#include 
#include 
#include 
#include 
void* cars(void* argc){
printf("(%lu) I INTEND to pass the fork\n",pthread_self());
sleep(1);
printf("(%lu) I am AT the fork\n",pthread_self());
sleep(1);
printf("(%lu) I have PASSED the fork\n",pthread_self());
sleep(1);
pthread_exit(0);
}
int main(int argc, char const* agrv[]){
pthread_t tid[5];
for (int i = 0; i < 5; i++){
pthread_create(tid+i, NULL, cars, NULL);
}
for (int i = 0; i < 5; i++){
pthread_join(tid[i], NULL);
}
return 0;
}

信号量(上)实验_第5张图片可以看到每五个进程都同时占用了临界区的通道,也就是临界区同时运行了五个进程,这个是有问题的

我们梳理一下逻辑,input是进入程序,at fork 和 passed fork是分支产生(冲突或者同步),所以at 和 passed这段区域是临界区,代码如下:

#include 
#include 
#include 
#include 
sem_t road;
void* cars(void* argc){    
printf("(%u) I INTEND to pass the fork\n",pthread_self());    
sleep(1);    
sem_wait(&road); // 执行P操作   
printf("(%u) I am AT the fork\n",pthread_self());    
sleep(1);    
printf("(%u) I have PASSED the fork\n",pthread_self());    
sleep(1);    
sem_post(&road); // 执行V操作    
pthread_exit(0);
}
int main(int argc, char const* agrv[]){  
pthread_t tid[5];    
sem_init(&road, 0, 2);    
for (int i = 0; i < 5; i++){        
pthread_create(tid+i, NULL, cars, NULL);    
}    
for (int i = 0; i < 5; i++){       
pthread_join(tid[i], NULL);   
}    
sem_destroy(&road);    
return 0;
  }

每个fork执行流一次可以跑两个分支,两分支同步。
同一时间段内只有两个能进入到fork里面,执行完成只有,另外两个才能进入。
信号量(上)实验_第6张图片

你可能感兴趣的:(操作系统,操作系统死锁,服务器运维,c++,c语言,linux,服务器,操作系统)