首页 > 其他分享 >实验四 信号量

实验四 信号量

时间:2023-10-16 15:44:56浏览次数:41  
标签:int 信号量 实验 pthread sleep sem include

使用二值信号量解决多线程售票系统数据错误问题

  • 实现代码
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
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;
}

一般信号量的观察

  • 1.没有使用信号量的情况下:

  • 该题示意图如下:

  • 我们现在有5个线程,但是只有两份资源可⽤;我们通过信号量去模拟这⼀种情况

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
void* cars(void* argc){
printf("(%u) I INTEND to pass the fork\n",pthread_self());
sleep(1);
printf("(%u) I am AT the fork\n",pthread_self());
sleep(1);
printf("(%u) 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;
}
  • 当我们的线程中没有使用sleep(1);方法时


可以发现这是我们的线程是一个一个通过的,好像没有什么问题。这是因为我们的线程太少以及我们的线程执行速度太快导致的。所以我们需要使用sleep方法将检查的速度降下来才能看到现象

  • 添加了sleep方法后的现象

    这样我们可以发现既然这5个线程同时都在fork,这和我们规定的只有2条线路(资源)可用的原理是违背的,他的这种运行逻辑是不正确的

  • 皆下面我们将这个问题加上信号量

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
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;
}

标签:int,信号量,实验,pthread,sleep,sem,include
From: https://www.cnblogs.com/swtaa/p/17767304.html

相关文章

  • 实验1 类和对象编程_基础编程1
    实验任务1task1.cpp//标准库string,vector,array基础用法#include<iostream>#include<string>#include<vector>#include<array>//函数模板//对满足特定条件的序列类型T对象,使用范围for输出template<typenameT>voidoutput1(constT&obj){for(aut......
  • 信号量机制和pv操作
           ......
  • 实验一
    任务一1#include<iostream>2#include<string>3#include<vector>4#include<array>5template<typenameT>6voidoutput1(constT&obj)7{8for(autoi:obj)9std::cout<<i<<",";10......
  • 实验三 互斥锁
    不加锁的多线程售票系统存在的问题售票系统实现代码#include<stdio.h>#include<pthread.h>#include<unistd.h>intticketAmout=2;//票的数量:全局变量void*ticketAgent(void*arg){intt=ticketAmout;if(t>0){printf("Oneticketsold\n");t--;}el......
  • 实验四报告: 熟悉Python字典、集合、字符串的使用
    实验目标本实验的主要目标是熟悉Python中字典、集合、字符串的创建和操作,包括字典的创建、访问、修改和合并,集合的创建、访问以及各种集合运算,以及字符串的创建、格式化和常用操作。实验要求通过编写Python代码,验证以下要求:熟悉Python字典的创建、访问、修改、合并。熟悉Pyt......
  • 可实现加、减、乘、除、开平方的计算器软件的实验设计
    1、思路代码:#include<stdio.h>#include<math.h>//牛顿迭代法计算平方根doublesqrt_newton(doublex){doubleguess=x/2.0;//初始猜测值为x的一半doubledelta=0.000001;//误差范围while(fabs(guess*guess-x)>delta){guess=(guess+x/guess)/2.0;......
  • 5381: C++实验:STL之search
    描述  使用STL中的search函数,判断一个序列是否是另一个序列的子序列。部分代码已经给出,请补充完整,提交时请勿包含已经给出的代码。  C++intmain(){vector<int>vec1,vec2;intn,m,a;cin>>n>>m;while(n--){cin>>a;......
  • 5383: C++实验:STL之multimap
    描述  使用STL中的multimap记录用户的所有电话号码,yuyu想查询用户有多少个电话号码,crq则想查询时输出所有的号码。部分代码已经给出,请补充完整,提交时请勿包含已经给出的代码。 C++intmain(){ multimap<string,string>sm; stringname,phone; intn; cin>>......
  • GPU实验室-在阿里云云上部署ChatGLM2-6B大模型
    实验室地址:https://developer.aliyun.com/adc/scenario/f3dc63dc55a543c3884b8dbd292adcd5一、先买机器并开通对应安全组8501端口规格族:GPU计算型gn6i实例规格:ecs.gn6i-c4g1.xlarge安全组新增规则入方向端口范围:8501/8501授权对象:0.0.0.0/0二、最好是安装系统的时候把安装nvidi......
  • 实验5实验6_102101310_黄心怡
    实验5实验6_102101310_黄心怡实验5:开源控制器实践——POX一、实验目的能够理解POX控制器的工作原理;通过验证POX的forwarding.hub和forwarding.l2_learning模块,初步掌握POX控制器的使用方法;能够运用POX控制器编写自定义网络应用程序,进一步熟悉POX控制器流表下发的方法。二......