当前位置: 首页 > article >正文

互斥与同步

1:思维导图

2:有一个隧道,长1000m,有一辆高铁,每秒100米,有一辆快车,每秒50m 要求模拟这两列火车通过隧道的场景

#include <stdio.h>
#include <string.h>
#include <unistd.h> 
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/un.h>

pthread_mutex_t m;
pthread_cond_t cond;
int a=0;

void *quit(void *arg)
{
	pthread_mutex_lock(&m);
	pthread_cond_wait(&cond,&m);
	for(int i=0;i<=1000;i+=50)
	{
		printf("快车行驶%d米\n",i);
	}
	printf("快车出隧道\n");
	pthread_mutex_unlock(&m);
}

typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;
typedef struct sockaddr_un addr_un_t;

int main(int argc, const char *argv[])
{
		printf("高铁进隧道\n");
	for(int i=0;i<=1000;i+=100)
	{
		printf("高铁行驶%d米\n",i);
	}
	printf("高铁出隧道\n");
	printf("快车准备进入\n");
	pthread_mutex_init(&m,NULL);
	pthread_cond_init(&cond,NULL);
	pthread_t id;
	pthread_create(&id,0,quit,0);
	usleep(100);
	pthread_detach(id); 
	pthread_cond_signal(&cond);
	usleep(100);
	return 0;
}

运行截图:

 

3:有一个隧道,长1000m,有一辆高铁,每秒100米,有一辆快车,每秒50m,有一辆慢车每秒25m 要求模拟这两列火车通过隧道的场景,但是要求高铁最先过隧道,快车其次,慢车最后

#include <stdio.h>
#include <string.h>
#include <unistd.h> 
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/un.h>

typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;
typedef struct sockaddr_un addr_un_t;

pthread_mutex_t m1;
pthread_mutex_t m2;
pthread_mutex_t m3;
void* task1(void * arg)
{
	pthread_mutex_lock(&m1);
	printf("高铁进入隧道\n");
	printf("高铁出隧道\n");
	pthread_mutex_unlock(&m2);
}

void* task2(void *arg)
{
	pthread_mutex_lock(&m2);
	printf("快车进入隧道\n");
	printf("快车出隧道\n");
	pthread_mutex_unlock(&m3);
}

void* task3(void *arg)
{
	pthread_mutex_lock(&m3);
	printf("慢车进入隧道\n");
	printf("慢车出隧道\n");
	pthread_mutex_unlock(&m1);
}


int main(int argc, const char *argv[])
{
	pthread_mutex_init(&m1,NULL);
	pthread_mutex_init(&m2,NULL);
	pthread_mutex_lock(&m2);
	pthread_mutex_init(&m3,NULL);
	pthread_mutex_lock(&m3);

	pthread_t id1,id2,id3;
	pthread_create(&id1,0,task1,0);
	pthread_create(&id2,0,task2,0);
	pthread_create(&id3,0,task3,0);
	pthread_detach(id1);
	pthread_detach(id2);
	pthread_detach(id3);

	usleep(1000);
	return 0;
}

运行截图:

 

4:使用条件变量实现一个生产者消费者模型(pv)模型 生产者线程:每秒生成2个苹果 消费者线程:没3秒消费 5~9个苹果 要求消费者在消费之前一定要有足够的苹果给消费

#include <stdio.h>
#include <string.h>
#include <unistd.h> 
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/un.h>
#include<time.h>

typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;
typedef struct sockaddr_un addr_un_t;

int a=0;//苹果数
int b=0;//每次消费数量
pthread_mutex_t m;//互斥锁
pthread_cond_t cond1;//条件变量


void *create(void *arg)//生成苹果
{
	while(1)
	{
		pthread_mutex_lock(&m);
		pthread_cond_wait(&cond1,&m);//唤醒
		a=a+6;//苹果数增加
		pthread_mutex_unlock(&m);
	}
}



int main(int argc, const char *argv[])
{
	pthread_t id1;
	pthread_create(&id1,0,create,0);
	pthread_detach(id1);

	while(1)
	{
		srand((unsigned)time(NULL));	
		b=5+rand()%5;//取5-9的随机数
		sleep(3);//休眠三秒
		pthread_cond_signal(&cond1);//符合条件
		usleep(1000);//让create成功执行
		if(a>=b)
		{
			a=a-b;//苹果的剩余量
			printf("消费成功\n");
			printf("消费苹果%d个,剩余%d个\n",b,a);
		}else{
			printf("消费不成功\n");
			printf("想要消费苹果%d个不成功,剩余%d个\n",b,a);
		}

	}
	
	return 0;
}

运行截图:

第四题在时间足够可能出现数据访问问题:

以下进行修改,改为互斥同步的状态

#include <stdio.h>
#include <string.h>
#include <unistd.h> 
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <wait.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <semaphore.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <sys/un.h>
#include<time.h>

typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;
typedef struct sockaddr_un addr_un_t;

int a=0;//苹果数
int b=0;//每次消费数量
pthread_mutex_t m1;//互斥锁
pthread_mutex_t m2;
pthread_cond_t cond1;//条件变量


void *create(void *arg)//生成苹果
{
	while(1)
	{
		pthread_mutex_lock(&m1);
		pthread_cond_wait(&cond1,&m1);//唤醒
		a=a+6;//苹果数增加
		pthread_mutex_unlock(&m2);
	}
}

void* buy(void* arg)
{

	while(1)
	{
		pthread_mutex_lock(&m2);
		srand((unsigned)time(NULL));	
		b=5+rand()%5;//取5-9的随机数
		sleep(3);//休眠三秒
		if(a>=b)
		{
			a=a-b;//苹果的剩余量
			printf("消费成功\n");
			printf("消费苹果%d个,剩余%d个\n",b,a);
		}else{
			printf("消费不成功\n");
			printf("想要消费苹果%d个不成功,剩余%d个\n",b,a);
		}
		pthread_mutex_unlock(&m1);
		
	}

}

int main(int argc, const char *argv[])
{
	pthread_mutex_init(&m1,NULL);
	pthread_mutex_init(&m2,NULL);
	pthread_cond_init(&cond1,NULL);

	pthread_t id1,id2;
	pthread_create(&id1,0,create,0);
	pthread_detach(id1);
	pthread_create(&id2,0,buy,0);
	pthread_detach(id2);

	while(1)
	{
		pthread_cond_signal(&cond1);//符合条件
	}
	
	return 0;
}

运行截图:


http://www.kler.cn/a/503836.html

相关文章:

  • ArkTS 组件事件、状态管理与资源管理
  • Vue2+OpenLayers使用Overlay实现点击获取当前经纬度信息(提供Gitee源码)
  • RabbitMQ 高可用方案:原理、构建与运维全解析
  • JSON.stringify(res,null,2)的含义
  • Java内存与缓存
  • OceanBase数据库设计与管理:构建高效分布式数据架构基石
  • 迅为RK3568开发板篇OpenHarmony配置HDF驱动控制LED-配置创建私有配置文件
  • Vue.js 组件的基本结构:模板、脚本和样式
  • Vue3组件设计模式:高可复用性组件开发实战
  • python+django+elasticsearch实现自动化部署平台构建日志记录(前端vue-element展示)
  • maven 下载依赖 jhash:2.1.2 和对应 jar 包
  • 基于Java的愤怒的小鸟游戏的设计与实现【源码+文档+部署讲解】
  • CSS | CSS实现两栏布局(左边定宽 右边自适应,左右成比自适应)
  • 支持Google Analytics快捷添加的CMS:费用与部署形式详解
  • 数据结构—《二叉树的定义与特性》
  • 软件设计模式的原则
  • pg_hba.conf是PostgreSQL中控制客户端认证和访问权限的配置文件
  • C# 将 List 转换为只读的 List
  • vue3 实现 “ fly-cut 在线视频剪辑 ”
  • 【MySQL】count(*)、count(1)和count(列名)区别
  • JAVA:利用 RabbitMQ 死信队列实现支付超时场景的技术指南
  • 第424场周赛:使数组元素等于零、零数组变换 Ⅰ、零数组变换 Ⅱ、最小化相邻元素的最大差值
  • OJ题目下篇
  • AI赋能下的美颜API与滤镜SDK:从传统到深度学习的进化之路
  • 深入理解 Python 的装饰器
  • Elasticsearch ES|QL 地理空间索引加入纽约犯罪地图