学习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的第八天
作业:使用信号灯循环输出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-日志模块的简单使用方法
扩展阅读: Python-Django的“日志功能-日志模块(logging模块)-日志输出”的功能详解 现在有下面的Python代码: # -*- coding: utf-8 -*-def log_out_test(content_out):print(content_out)content1 "i love you01" log_out_test(content1)现…...
argparse --- 命令行选项、参数和子命令解析器
3.2 新版功能. 源代码: Lib/argparse.py 教程 此页面包含该 API 的参考信息。有关 Python 命令行解析更细致的介绍,请参阅 argparse 教程。 argparse 模块可以让人轻松编写用户友好的命令行接口。 程序定义它需要哪些参数,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 个城市,编号为 1 … N …...
fastadmin配置教程
第一. 打开小皮,创建一个网站 第二. 打开fastadmin官网,下载压缩包 下载好后是这个样子 打开网站的根目录,将这个压缩包压缩到你网站的根目录里 第三,小皮里面创建一个数据库 第四,然后打开网站,输入创…...
golang游戏服务器 - tgf系列课程01
TGF框架的特点和功能 课程介绍了TGF框架的特点和功能在第一节课程中我们并不会介绍框架的使用。我们希望在这节课程中,能让你了解到tgf是一个什么样的框架 概要 本节课程介绍了TGF框架的特点和功能。TGF是一个开箱即用的服务器框架, 适合中小型团队和独立开发者进行游戏开发。…...
react dom的diff理解及性能优化
diff的三大过程 当某个值变化时,他从根组件寻找 (key,state,props,context) 当父组件稳定时,react会跳过子组件的props的对比 只有当当前组件值改变时,从他开始,所有的子孙节点都会对比props props是全等比较,所以&am…...
【acwing】92. 递归实现指数型枚举
穿越隧道 递归枚举、位运算 方法① 从1到n,顺序访问每位数,是否选择,每位数有两种状态,选1或不选0. AC代码如下: #include <iostream> using namespace std;const int N 100; // bool st[N]; int n;void dfs(in…...
【面试】Java最新面试题资深开发-分布式系统中的CAP理论
问题六:分布式系统中的CAP理论 分布式系统的设计涉及到CAP理论,即一致性(Consistency)、可用性(Availability)、分区容忍性(Partition Tolerance)。请解释一下CAP理论是什么&#x…...
Windows下使用CMD修改本地IP
在网络适配器界面查看当前网线连接的哪个网口,我当前连的是 以太网 这个名字的: 在windows下使用管理员权限打开CMD命令工具,输入如下命令(如我想本地ip改成192.168.2.4): 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标签:win10 22h2 wepe dism分栏:WINDOWS 二、硬件环境 8G或以上的有PE功能的启动U盘一个台式机…...
前端知识笔记(五)———前端密钥怎么存储,才最安全?
前端密钥存储安全是非常重要的,具体原因如下: 保护敏感数据:密钥用于保护敏感数据的安全性。如果密钥泄露,攻击者可能能够访问和篡改敏感数据,导致数据泄露、数据被篡改或系统被入侵。 防止恶意使用:在前端…...
【智能家居】智能家居项目
智能家居项目目录 项目目录结构 完整而典型的项目目录结构 CMake模板 CMake编译运行 README.md 项目说明文档 智能家居项目目录 【智能家居】面向对象编程OOP和设计模式(工厂模式) 【智能家居】一、工厂模式实现继电器灯控制 【智能家居】二、添加火灾检测模块(…...
在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 控件用来输入要浏览的网页地址,Button控件用来执行浏览网页操作, WebBrowser控件用来显示要浏览的网页。这个控…...
MacOS 14挂载NTFS 硬盘的最佳方式(免费)
categories: [Tips] tags: MacOS 写在前面 众所周知, MacOS 上面插入 NTFS磁盘格式的话, 磁盘可以向 Mac 写入数据, 但是 Mac 上的数据不能写入磁盘(这是因为 MacOS 的内核扩展禁用了 NTFS 这个格式, 可能是出于安全性或其他原因) 之前一直是使用某 pojie 的 NTFS 工具的, 虽然…...
SpringAOP专栏二《原理篇》
上一篇SpringAOP专栏一《使用教程篇》-CSDN博客介绍了SpringAop如何使用,这一篇文章就会介绍Spring AOP 的底层实现原理,并通过源代码解析来详细阐述其实现过程。 前言 Spring AOP 的实现原理是基于动态代理和字节码操作的。不了解动态代理和字节码操作…...
冒泡排序(函数)
冒泡排序,将一个列表中的两个元素进行比较,并将最小的元素交换到顶部。两个元素中较小的会冒到顶部,而较大的会沉到底部,该过程将被重复执行,直到所有元素都被排序。 输入格式: 输入在第1行中给出N(1<N…...
Vue3中的defineModel
目录 一、vue3的defineModel介绍 二、defineModel使用 (1)在vite.config.js中开启 (2)子组件 (3)父组件 一、vue3的defineModel介绍 为什么要使用到defineModel呢?这里有这样一种场景&…...
通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》
在注意力分散、内容高度同质化的时代,情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现,消费者对内容的“有感”程度,正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中࿰…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
Neko虚拟浏览器远程协作方案:Docker+内网穿透技术部署实践
前言:本文将向开发者介绍一款创新性协作工具——Neko虚拟浏览器。在数字化协作场景中,跨地域的团队常需面对实时共享屏幕、协同编辑文档等需求。通过本指南,你将掌握在Ubuntu系统中使用容器化技术部署该工具的具体方案,并结合内网…...
Python训练营-Day26-函数专题1:函数定义与参数
题目1:计算圆的面积 任务: 编写一个名为 calculate_circle_area 的函数,该函数接收圆的半径 radius 作为参数,并返回圆的面积。圆的面积 π * radius (可以使用 math.pi 作为 π 的值)要求:函数接收一个位置参数 radi…...
用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章
用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章 摘要: 操作系统内核的安全性、稳定性至关重要。传统 Linux 内核模块开发长期依赖于 C 语言,受限于 C 语言本身的内存安全和并发安全问题,开发复杂模块极易引入难以…...
