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

学习IO的第八天

作业:使用信号灯循环输出ABC

sem.c

#include <head.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_sem(int semid, int semno)
{int val = -1;printf("请输入编号为%d的灯的初始值:", semno);scanf("%d", &val);getchar();     //吸收scanf留下的回车//对当前灯进行赋初始值//定义一个共用体变量union semun us;us.val = val;           //要赋的值if(semctl(semid, semno, SETVAL, us) == -1){perror("semctl error\n");return -1;}//成功返回0return 0;
}//信号灯集的申请,初始化信号灯,并返回信号灯集的id
int create_sem(int semcount)
{//1.创建key值key_t key = ftok("/", 'y');if(key == -1){perror("ftok error\n");return -1;}//2.通过key值创建一个信号灯集int semid = semget(key, semcount, IPC_CREAT|IPC_EXCL|0664);if(semid == -1){if(errno == EEXIST){//信号灯集已经存在,无需创建直接打开即可semid = semget(key, semcount, IPC_CREAT);return semid;            //之后的进程打开信号灯集只需返回id即可,无需进行初始化操作}perror("semget error\n");return -1;}//3.给信号灯集中的信号灯进行初始化操作for(int i=0;i<semcount;i++){init_sem(semid, i);         //初始化编号为i的灯value值}//4.返回信号灯集的idreturn semid;
}//申请信号灯资源操作P操作
int P(int semid, int semno)
{//定一个操作的结构体变量struct sembuf buf;buf.sem_num = semno;      //要操作的灯的编号buf.sem_op = -1;          //表示申请资源操作buf.sem_flg = 0;          //如果没有资源,则阻塞等待//调用semop函数完成P操作if(semop(semid, &buf, 1) == -1){perror("semop error\n");return -1;}return 0;       //成功返回0
}//释放信号灯资源操作 v操作
int V(int semid, int semno)
{//定一个操作的结构体变量struct sembuf buf;buf.sem_num = semno;      //要操作的灯的编号buf.sem_op = 1;          //表示释放资源操作buf.sem_flg = 0;          //如果没有资源,则阻塞等待//调用semop函数完成V操作if(semop(semid, &buf, 1) == -1){perror("semop error\n");return -1;}return 0;       //成功返回0}//信号灯集的删除
int del_sem(int semid)
{if(semctl(semid, 0, IPC_RMID, 0) == -1){perror("del error\n");return -1;}return 0;
}

主函数

#include <head.h>
#include "sem.h"#define PAGE_SIZE 4096int main(int argc, const char *argv[])
{//创建一个信号灯集int semid = create_sem(3);       //创建一个信号灯集包含两个灯,并初始化if(semid == -1){perror("create_sem error\n");return -1;}//创建的key值key_t key = ftok("/", 'y');if(key == -1){perror("ftok error\n");return -1;}printf("key = %#x\n", key);//通过key值创建共享内存段int shmid = shmget(key, PAGE_SIZE, IPC_CREAT|0664);if(shmid == -1){perror("shmget error\n");return -1;}printf("shmid = %d\n", shmid);//将共享内存段映射到用户空间char *addr = (char *)shmat(shmid, NULL, 0);if(addr == (void *)-1){perror("shmat error\n");return -1;}printf("addr = %p\n", addr);     //输出映射的虚拟地址pid_t pid = -1;pid = fork();if(pid > 0){pid_t pid2 = fork();if(pid2 > 0){//父进程int count =0;while(1){//V操作,释放1灯的资源				P(semid,0);printf("A");count++;fflush(stdout);    //每个进程的用户空间相互独立,缓冲区不同V(semid,1);if(count == 5){break;}}	wait(NULL);wait(NULL);wait(NULL);}else if(pid2 == 0){//子进程2int count=0;while(1){//P操作,等待0灯的资源P(semid, 2);printf("C\n");count++;V(semid, 0);if(count == 5){break;}}exit(EXIT_SUCCESS);}else{perror("fork2 error\n");return -1;}}else if(pid == 0){//子进程1int count=0;while(1){//P操作,等待1号灯的资源P(semid, 1);printf("B");count++;fflush(stdout);//V操作,释放0号灯的资源V(semid,2);if(count == 5){break;}}exit(EXIT_SUCCESS);}else {perror("fork1 error\n");return -1;}if(shmdt(addr) == -1){perror("shmdt error\n");return -1;}del_sem(semid);return 0;
}

现象

相关文章:

学习IO的第八天

作业&#xff1a;使用信号灯循环输出ABC sem.c #include <head.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 seminf…...

【clickhouse】ck远程访问另一个ck

代码实现 CREATE TABLE tmp.tbsas remote( host, database_name, table_name, user, password );就相当于从ck1直接请求ck2 参考文档 https://github.com/ClickHouse/ClickHouse/issues/15295 https://clickhouse.com/docs/zh/sql-reference/table-functions/remote...

Django的logging-日志模块的简单使用方法

扩展阅读&#xff1a; Python-Django的“日志功能-日志模块(logging模块)-日志输出”的功能详解 现在有下面的Python代码&#xff1a; # -*- coding: utf-8 -*-def log_out_test(content_out):print(content_out)content1 "i love you01" log_out_test(content1)现…...

​argparse --- 命令行选项、参数和子命令解析器​

3.2 新版功能. 源代码&#xff1a; Lib/argparse.py 教程 此页面包含该 API 的参考信息。有关 Python 命令行解析更细致的介绍&#xff0c;请参阅 argparse 教程。 argparse 模块可以让人轻松编写用户友好的命令行接口。 程序定义它需要哪些参数&#xff0c;argparse 将会知…...

洛谷 P8802 [蓝桥杯 2022 国 B] 出差

文章目录 [蓝桥杯 2022 国 B] 出差题目链接题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示 思路解析CODE [蓝桥杯 2022 国 B] 出差 题目链接 https://www.luogu.com.cn/problem/P8802 题目描述 A \mathrm{A} A 国有 N N N 个城市&#xff0c;编号为 1 … N …...

fastadmin配置教程

第一. 打开小皮&#xff0c;创建一个网站 第二. 打开fastadmin官网&#xff0c;下载压缩包 下载好后是这个样子 打开网站的根目录&#xff0c;将这个压缩包压缩到你网站的根目录里 第三&#xff0c;小皮里面创建一个数据库 第四&#xff0c;然后打开网站&#xff0c;输入创…...

golang游戏服务器 - tgf系列课程01

TGF框架的特点和功能 课程介绍了TGF框架的特点和功能在第一节课程中我们并不会介绍框架的使用。我们希望在这节课程中,能让你了解到tgf是一个什么样的框架 概要 本节课程介绍了TGF框架的特点和功能。TGF是一个开箱即用的服务器框架, 适合中小型团队和独立开发者进行游戏开发。…...

react dom的diff理解及性能优化

diff的三大过程 当某个值变化时&#xff0c;他从根组件寻找 (key,state,props,context) 当父组件稳定时&#xff0c;react会跳过子组件的props的对比 只有当当前组件值改变时&#xff0c;从他开始&#xff0c;所有的子孙节点都会对比props props是全等比较&#xff0c;所以&am…...

【acwing】92. 递归实现指数型枚举

穿越隧道 递归枚举、位运算 方法① 从1到n&#xff0c;顺序访问每位数&#xff0c;是否选择&#xff0c;每位数有两种状态&#xff0c;选1或不选0. AC代码如下&#xff1a; #include <iostream> using namespace std;const int N 100; // bool st[N]; int n;void dfs(in…...

【面试】Java最新面试题资深开发-分布式系统中的CAP理论

问题六&#xff1a;分布式系统中的CAP理论 分布式系统的设计涉及到CAP理论&#xff0c;即一致性&#xff08;Consistency&#xff09;、可用性&#xff08;Availability&#xff09;、分区容忍性&#xff08;Partition Tolerance&#xff09;。请解释一下CAP理论是什么&#x…...

Windows下使用CMD修改本地IP

在网络适配器界面查看当前网线连接的哪个网口&#xff0c;我当前连的是 以太网 这个名字的&#xff1a; 在windows下使用管理员权限打开CMD命令工具&#xff0c;输入如下命令(如我想本地ip改成192.168.2.4)&#xff1a; netsh interface ip set address "以太网" st…...

20231211-DISM++安装win10-22h2-oct

20231211-DISM安装win10-22h2-oct 一、软件环境 zh-cn_windows_10_consumer_editions_version_22h2_updated_oct_2023_x64_dvd_eb811ccc.isowepe x64 v2.3标签&#xff1a;win10 22h2 wepe dism分栏&#xff1a;WINDOWS 二、硬件环境 8G或以上的有PE功能的启动U盘一个台式机…...

前端知识笔记(五)———前端密钥怎么存储,才最安全?

前端密钥存储安全是非常重要的&#xff0c;具体原因如下&#xff1a; 保护敏感数据&#xff1a;密钥用于保护敏感数据的安全性。如果密钥泄露&#xff0c;攻击者可能能够访问和篡改敏感数据&#xff0c;导致数据泄露、数据被篡改或系统被入侵。 防止恶意使用&#xff1a;在前端…...

【智能家居】智能家居项目

智能家居项目目录 项目目录结构 完整而典型的项目目录结构 CMake模板 CMake编译运行 README.md 项目说明文档 智能家居项目目录 【智能家居】面向对象编程OOP和设计模式(工厂模式) 【智能家居】一、工厂模式实现继电器灯控制 【智能家居】二、添加火灾检测模块&#xff08;…...

在AWS Lambda上部署标准FFmpeg工具——Docker方案

大纲 1 确定Lambda运行时环境1.1 Lambda系统、镜像、内核版本1.2 运行时1.2.1 Python1.2.2 Java 2 启动EC23 编写调用FFmpeg的代码4 生成docker镜像4.1 安装和启动Docker服务4.2 编写Dockerfile脚本4.3 生成镜像 5 推送镜像5.1 创建存储库5.2 给EC2赋予角色5.2.1 创建策略5.2.2…...

C#网络应用程序(Web页面浏览器、局域网聊天程序)

目录 一、创建Web页面浏览器 1.示例源码 2.生成效果 二、局域网聊天程序 1.类 2.服务器端 3.客户端 一、创建Web页面浏览器 TextBox 控件用来输入要浏览的网页地址&#xff0c;Button控件用来执行浏览网页操作&#xff0c; WebBrowser控件用来显示要浏览的网页。这个控…...

MacOS 14挂载NTFS 硬盘的最佳方式(免费)

categories: [Tips] tags: MacOS 写在前面 众所周知, MacOS 上面插入 NTFS磁盘格式的话, 磁盘可以向 Mac 写入数据, 但是 Mac 上的数据不能写入磁盘(这是因为 MacOS 的内核扩展禁用了 NTFS 这个格式, 可能是出于安全性或其他原因) 之前一直是使用某 pojie 的 NTFS 工具的, 虽然…...

SpringAOP专栏二《原理篇》

上一篇SpringAOP专栏一《使用教程篇》-CSDN博客介绍了SpringAop如何使用&#xff0c;这一篇文章就会介绍Spring AOP 的底层实现原理&#xff0c;并通过源代码解析来详细阐述其实现过程。 前言 Spring AOP 的实现原理是基于动态代理和字节码操作的。不了解动态代理和字节码操作…...

冒泡排序(函数)

冒泡排序&#xff0c;将一个列表中的两个元素进行比较&#xff0c;并将最小的元素交换到顶部。两个元素中较小的会冒到顶部&#xff0c;而较大的会沉到底部&#xff0c;该过程将被重复执行&#xff0c;直到所有元素都被排序。 输入格式: 输入在第1行中给出N&#xff08;1<N…...

Vue3中的defineModel

目录 一、vue3的defineModel介绍 二、defineModel使用 &#xff08;1&#xff09;在vite.config.js中开启 &#xff08;2&#xff09;子组件 &#xff08;3&#xff09;父组件 一、vue3的defineModel介绍 为什么要使用到defineModel呢&#xff1f;这里有这样一种场景&…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...

【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制

使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下&#xff0c;限制某个 IP 的访问频率是非常重要的&#xff0c;可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案&#xff0c;使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

逻辑回归暴力训练预测金融欺诈

简述 「使用逻辑回归暴力预测金融欺诈&#xff0c;并不断增加特征维度持续测试」的做法&#xff0c;体现了一种逐步建模与迭代验证的实验思路&#xff0c;在金融欺诈检测中非常有价值&#xff0c;本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...

Qt 事件处理中 return 的深入解析

Qt 事件处理中 return 的深入解析 在 Qt 事件处理中&#xff0c;return 语句的使用是另一个关键概念&#xff0c;它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别&#xff1a;不同层级的事件处理 方…...

离线语音识别方案分析

随着人工智能技术的不断发展&#xff0c;语音识别技术也得到了广泛的应用&#xff0c;从智能家居到车载系统&#xff0c;语音识别正在改变我们与设备的交互方式。尤其是离线语音识别&#xff0c;由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力&#xff0c;广…...