IO进程线程day8作业

news2024/11/18 17:40:47

信号灯集二次函数封装

sem.c

#include<myhead.h>

union semun
{
	int              val;    /* Value for SETVAL */
	struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
	unsigned short  *array;  /* Array for GETALL, SETALL */
	struct seminfo  *__buf;  /* Buffer for IPC_INFO
								(Linux-specific) */
};

//定义给信号灯集中的指定信号灯进行赋值
int init_semno(int semid,int semno)
{
	union semun buf;
	printf("请输入要给编号为%d的灯设置的值:",semno);
	scanf("%d",&buf.val);
	getchar();

	//调用控制函数
	if(semctl(semid,semno,SETVAL,buf)==-1)
	{
		perror("semctl error");
		return -1;
	}
	return 0;
}
//创建或打开共享内存
int open_sem(int semcount)
{
	//创建key值
	key_t key=-1;
	if((key=ftok("/",'s'))==-1)
	{
		perror("ftok error");
		return -1;
	}

	//通过key值创建一个信号灯集
	int semid =-1;
	if((semid=semget(key,semcount,IPC_CREAT|0064))==-1)
	{
		//对错误码进行判断,
		if(errno==EEXIST)
		{
			//直接打开信号灯集即可
			semid=semget(key,semcount,IPC_CREAT|0664);
			return semid;
		}
		perror("semget error");
		return -1;
	}

	//给信号灯集中的每个灯进行初始化
	for(int i=0;i<semcount;i++)
	{
		init_semno(semid,i);
	}

	return semid;
}

//进行资源申请操作
int P(int semid,int semno)
{
	//定义要进行的结构体变量
	struct sembuf buf;
	buf.sem_num=semno;
	buf.sem_op=-1;
	buf.sem_flg=0;

	//执行函数
	if(semop(semid,&buf,1)==-1)
	{
		perror("P error");
		return -1;
	}
	return 0;
}


//进行资源释放操作
int V(int semid,int semno)
{
	//定义要进行的结构体变量
	struct sembuf buf;
	buf.sem_num=semno;
	buf.sem_op=1;
	buf.sem_flg=0;

	//执行函数
	if(semop(semid,&buf,1)==-1)
	{
		perror("V error");
		return -1;
	}
	return 0;
}

//删除信号灯集
int del_sem(int semid)
{
	//删除信号灯集
	if(semctl(semid,0,IPC_RMID)==-1)
	{
		perror("delete error");
		return -1;
	}
	return 0;
}

sem.h

#ifndef _SEM_H_
#define _SEM_H_
//创建或打开共享内存:参数为要申请的信号灯集中包含的灯的个数,返回信号灯集的id
int open_sem(int semcount);


//进行资源申请操作:参数为要申请的信号灯id,以及灯的编号
int P(int semid,int semno);



//进行释放资源操作:参数为要申请的信号灯,以及灯的编号
int V(int semid,int semno);



//删除信号灯集的操作:参数为要删除的信号灯集id
int del_sem(int semid);




#endif

shmsnd.c

#include<myhead.h>

union semun
{
	int              val;    /* Value for SETVAL */
	struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
	unsigned short  *array;  /* Array for GETALL, SETALL */
	struct seminfo  *__buf;  /* Buffer for IPC_INFO
								(Linux-specific) */
};

//定义给信号灯集中的指定信号灯进行赋值
int init_semno(int semid,int semno)
{
	union semun buf;
	printf("请输入要给编号为%d的灯设置的值:",semno);
	scanf("%d",&buf.val);
	getchar();

	//调用控制函数
	if(semctl(semid,semno,SETVAL,buf)==-1)
	{
		perror("semctl error");
		return -1;
	}
	return 0;
}
//创建或打开共享内存
int open_sem(int semcount)
{
	//创建key值
	key_t key=-1;
	if((key=ftok("/",'s'))==-1)
	{
		perror("ftok error");
		return -1;
	}

	//通过key值创建一个信号灯集
	int semid =-1;
	if((semid=semget(key,semcount,IPC_CREAT|0064))==-1)
	{
		//对错误码进行判断,
		if(errno==EEXIST)
		{
			//直接打开信号灯集即可
			semid=semget(key,semcount,IPC_CREAT|0664);
			return semid;
		}
		perror("semget error");
		return -1;
	}

	//给信号灯集中的每个灯进行初始化
	for(int i=0;i<semcount;i++)
	{
		init_semno(semid,i);
	}

	return semid;
}

//进行资源申请操作
int P(int semid,int semno)
{
	//定义要进行的结构体变量
	struct sembuf buf;
	buf.sem_num=semno;
	buf.sem_op=-1;
	buf.sem_flg=0;

	//执行函数
	if(semop(semid,&buf,1)==-1)
	{
		perror("P error");
		return -1;
	}
	return 0;
}


//进行资源释放操作
int V(int semid,int semno)
{
	//定义要进行的结构体变量
	struct sembuf buf;
	buf.sem_num=semno;
	buf.sem_op=1;
	buf.sem_flg=0;

	//执行函数
	if(semop(semid,&buf,1)==-1)
	{
		perror("V error");
		return -1;
	}
	return 0;
}

//删除信号灯集
int del_sem(int semid)
{
	//删除信号灯集
	if(semctl(semid,0,IPC_RMID)==-1)
	{
		perror("delete error");
		return -1;
	}
	return 0;
}




ubuntu@ubuntu:~/IO进程线程/2.26/sem$ 
ubuntu@ubuntu:~/IO进程线程/2.26/sem$ sem.h
sem.h:未找到命令
ubuntu@ubuntu:~/IO进程线程/2.26/sem$ cat sem.h
#ifndef _SEM_H_
#define _SEM_H_
//创建或打开共享内存:参数为要申请的信号灯集中包含的灯的个数,返回信号灯集的id
int open_sem(int semcount);


//进行资源申请操作:参数为要申请的信号灯id,以及灯的编号
int P(int semid,int semno);



//进行释放资源操作:参数为要申请的信号灯,以及灯的编号
int V(int semid,int semno);



//删除信号灯集的操作:参数为要删除的信号灯集id
int del_sem(int semid);




#endif
ubuntu@ubuntu:~/IO进程线程/2.26/sem$ 







ubuntu@ubuntu:~/IO进程线程/2.26/sem$ cat shmsnd.c
#include<myhead.h>
#include"sem.h"
//一页大小
#define PAGE_SIZE 4096
int main(int argc, const char *argv[])
{
	//11.创建信号灯集
	int semid=open_sem(2);

	//1.创建key值
	key_t key=-1;
	if((key=ftok("/",'k'))==-1)
	{
		perror("ftok error");
		return -1;
	}
	printf("key=%d\n",key);

	//2.通过keu值创建一个共享内存
	int shmid=-1;
	if((shmid=shmget(key,PAGE_SIZE,IPC_CREAT|0064))==-1)
	{
		perror("shmget error");
		return -1;
	}
	printf("shmid=%d\n",shmid);

	//3.将共享内存段的数据映射到内存空间
	char *addr = shmat(shmid,NULL,0);

	if(addr==(void*)-1)
	{
		perror("shmat error");
		return -1;
	}
	printf("addr=%p\n",addr);

	//4.使用共享内存
	while(1)
	{
		//22.申请0号灯的资源
		P(semid,0);

		printf("please enter:");
		fgets(addr,PAGE_SIZE,stdin);
		addr[strlen(addr)-1]=0;

		printf("数据发送成功\n");

		//33.释放一号灯的资源
		V(semid,1);

		//判断输入内容
		if(strcmp(addr,"quit")==0)
		{
			break;
		}
	}

	//5.取消映射关系
	if(shmdt(addr)==-1)
	{
		perror("shmdt error");
		return -1;
	}

	//6.删除共享内存
	if(shmctl(shmid,IPC_RMID,NULL)==-1)
	{
		perror("shmctl error");
		return -1;
	}


	return 0;
}

shmrcv.c

#include<myhead.h>
#include"sem.h"
//一页大小
#define PAGE_SIZE 4096
int main(int argc, const char *argv[])
{
	//11.创建信号灯集
	int semid = open_sem(2);

	//1.创建key值
	key_t key=-1;
	if((key=ftok("/",'k'))==-1)
	{
		perror("ftok error");
		return -1;
	}
	printf("key=%d\n",key);

	//2.通过key值创建一个共享内存
	int shmid=-1;
	if((shmid=shmget(key,PAGE_SIZE,IPC_CREAT|0064))==-1)
	{
		perror("shmget error");
		return -1;
	}
	printf("shmid=%d\n",shmid);

	//3.将共享内存段的数据映射到内存空间
	char *addr = shmat(shmid,NULL,0);

	if(addr==(void*)-1)
	{
		perror("shmat error");
		return -1;
	}
	printf("addr=%p\n",addr);


	//4.使用共享内存
	while(1)
	{
		//22.申请一号灯的资源
		P(semid,1);

	//	sleep(1);
		printf("get text:%s\n",addr);


		//判断读取内容
		if(strcmp(addr,"quit")==0)
		{
			break;
		}

		//33.释放0号灯的资源
		V(semid,0);

	}

	//5.取消映射关系
	if(shmdt(addr)==-1)
	{
		perror("shmdt error");
		return -1;
	}

	//44.删除信号灯集
	del_sem(semid);


	return 0;
}

思维导图:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1472609.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

wps 365 批量修改.xlsx、.xls,单元格内容的格式为yyyy-mm-dd

xlsx、xls文件导入校验单元格内容格式有误&#xff0c;批量修改步骤如下 1.选中要修改内容的单元格列 2.选择数据-分列-分列&#xff0c;弹出“文本分列向导”弹窗 3.选择“下一步”——“下一步”到步骤3&#xff0c;在“列数据类型”中选中日期-YMD格式&#xff0c;点击“完成…

protobuf某音弹幕实战

声明:(如果侵犯到你的权益联系我&#xff0c;我会马上删除) 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;不提供完整代码&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由…

2.20 day2 QT

自由发挥登录窗口的应用场景&#xff0c;实现一个登录窗口界面 #include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent) {//窗口相关设置this->setWindowTitle("登入页面"); //设置 窗口 标题this->setWindowIcon(QIcon("D:…

2024Python自动化测试面试必备知识点!

在准备 Python 自动化测试面试时&#xff0c;以下是一些必备的知识点&#xff0c;可以帮助您在面试中展现实力&#xff1a; 软件测试基础&#xff1a; 熟悉软件测试的基本概念&#xff0c;包括测试类型&#xff08;功能测试、性能测试、安全测试等&#xff09;、测试方法&#…

HTTP与HTTPS-HTTPS 的应用数据是如何保证完整性的?

资料来源 : 小林coding 小林官方网站 : 小林coding (xiaolincoding.com) HTTPS 的应用数据是如何保证完整性的? TLS 在实现上分为握手协议和记录协议两层 TLS 握手协议就是我们前面说的 TLS 四次握手的过程&#xff0c;负责协商加密算法和生成对称密钥&#xff0c;后续用此密…

C++ //练习 9.19 重写上题的程序,用list替代deque。列出程序要做出哪些改变。

C Primer&#xff08;第5版&#xff09; 练习 9.19 练习 9.19 重写上题的程序&#xff0c;用list替代deque。列出程序要做出哪些改变。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 //头文件需要调整为list&#xff0c;同时…

猫头虎分享已解决Bug || ValueError: No gradients provided for any variable

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

代码随想录算法训练营第三十二天|122 买卖股票的最佳时机||、55 跳跃游戏、45 跳跃游戏||

122 买卖股票的最佳时机|| 题目链接&#xff1a;买卖股票的最佳时机|| 思路 这道题目求的是获得的最大利润是多少。我们只需要收集正利润&#xff0c;便可求得最大利润。 class Solution { public:int maxProfit(vector<int>& prices) {int res 0;for(int i1; i…

Python炒股自动化(2):获取股票实时数据和历史数据

如果你是一位大佬&#xff0c;看我前面的分享即可&#xff0c;相信你有自己的思路&#xff0c;或者已经有了成熟的策略&#xff0c;你需要的只是API接口来实现你的想法&#xff0c;前面的分享是你需要的&#xff0c;这些是给刚开始接触程序交易的朋友分享的。 前面发了股票程序…

【K8s】初识PV和PVC

​ 目录 收起 O、致谢 一、前言 二、Volume 2.1 什么是Volume 2.2 为什么要引入Volume 2.3 Volume类型有哪些 2.4 Volume如何使用 2.4.1 通过emptyDir共享数据 2.4.2 使用HostPath挂载宿主机文件 2.4.3 挂载NFS至容器 三、PV和PVC 3.1 什么是PV和PVC 3.2 为什么要引入PV和PVC 3…

「哈哥赠书活动 - 48期」-『商业分析思维与实践:用数据分析解决商业问题宣传文案』

⭐️ 赠书 - 《商业分析思维与实践》 ⭐️ 内容简介 本书以业务为导向&#xff0c;详细地讲解了如何通过大数据分析来解决商业问题。其目的在于运用大数据分析思维&#xff0c;帮助读者把学术知识应用于真实的业务场景&#xff0c;解决实际的业务问题。本书基于业务问题&#x…

鸿蒙 渲染控制

前提&#xff1a;基于官网3.1/4.0文档。参考官网文档 基于Android开发体系来进行比较和思考。&#xff08;或有偏颇&#xff0c;自行斟酌&#xff09; 1.概念 ArkUI通过自定义组件的build()函数和builder装饰器中的声明式UI描述语句构建相应的UI。在声明式描述语句中开发者除了…

GEE必须会教程—矢量数据类型

矢量这个词&#xff0c;我们在数学上并不陌生&#xff0c;它是既有方向又有大小的量。而在GIS中&#xff0c;常常利用欧氏空间的点、线、面来表示地理实体&#xff0c;进而构成我们使用频繁的矢量数据&#xff0c;它和栅格数据一同构成了地理信息数据的基础。今天开始&#xff…

AI:140-使用强化学习优化供应链管理

🚀点击这里跳转到本专栏,可查阅专栏顶置最新的指南宝典~ 🎉🎊🎉 你的技术旅程将在这里启航! 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 ✨✨✨ 每一个案例都附带关键代码,详细讲解供大家学习,希望…

typecho 给文章创建目录树

受益于 shortcode 短代码插件和泽泽短代码中目录树的显示样式&#xff0c;形成了自己实现添加文章目录的思路&#xff1a; 一、文章目录树的结构 <div id"toc"><div class"toc-left"><div class"toc-btn" type"button&quo…

网络技术ensp 一个简单的交换机配置案例

由于工作调岗&#xff0c;转战网络运维了&#xff0c;第一次网络笔记 1.&#xff0c;目的&#xff1a;2台主机相互可以ping通&#xff0c;并且可以ping通网关地址&#xff0c;设备&#xff1a;2台主机&#xff0c;2台交换机 2网络拓扑图如下 3.主机pc1的配置信息 ip&#xff…

一个Post请求入门NestJS的路由与控制器

​ NestJS的控制器 控制器负责处理传入请求并向客户端返回响应。 控制器的目的是接收应用的特定请求。路由机制控制哪个控制器接收哪些请求。 通常&#xff0c;每个控制器都有不止一条路由&#xff0c;不同的路由可以执行不同的操作。 在使用了脚手架的项目中&#xff0c;我…

javascript给对象添加迭代器

迭代器是啥就自行百度了 为啥for…of可以遍历数组&#xff0c;为啥不能遍历对象&#xff0c;就是for…of会调用迭代器&#xff0c;而数组是内置了迭代器了&#xff0c;而对象没有内置&#xff0c;所以直接使用for…of遍历对象会报错&#xff0c;因此只用在对象的原型上面自定义…

temu/亚马逊美国站烧烤炉UL报告UL2728A应该怎么办理?

temu/亚马逊美国站烧烤炉UL报告UL2728A应该怎么办理&#xff1f; 近年来&#xff0c;烧烤炉在美国市场越来越受欢迎&#xff0c;其便捷性和独特的烹饪方式吸引了许多消费者。然而&#xff0c;为了确保产品的安全性和质量&#xff0c;美国市场对于烧烤炉产品的上架要求日益严格…

Python中的atexit模块:优雅地处理程序退出

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站AI学习网站。 目录 前言 atexit模块概述 atexit模块的基本用法 示例代码&#xff1a;文件操作时的应用场景 典型应用场景 1 资源释放…