当前位置: 首页 > 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;
}

现象

http://www.lryc.cn/news/258385.html

相关文章:

  • 【clickhouse】ck远程访问另一个ck
  • Django的logging-日志模块的简单使用方法
  • ​argparse --- 命令行选项、参数和子命令解析器​
  • 洛谷 P8802 [蓝桥杯 2022 国 B] 出差
  • fastadmin配置教程
  • golang游戏服务器 - tgf系列课程01
  • react dom的diff理解及性能优化
  • 【acwing】92. 递归实现指数型枚举
  • 【面试】Java最新面试题资深开发-分布式系统中的CAP理论
  • Windows下使用CMD修改本地IP
  • 20231211-DISM++安装win10-22h2-oct
  • 前端知识笔记(五)———前端密钥怎么存储,才最安全?
  • 【智能家居】智能家居项目
  • 在AWS Lambda上部署标准FFmpeg工具——Docker方案
  • C#网络应用程序(Web页面浏览器、局域网聊天程序)
  • MacOS 14挂载NTFS 硬盘的最佳方式(免费)
  • SpringAOP专栏二《原理篇》
  • 冒泡排序(函数)
  • Vue3中的defineModel
  • 动态内存管理(C语言)
  • 区块链实验室(32) - 下载arm64的Prysm
  • flutter学习-day3-dart基础
  • gitblit自建git仓库
  • 二百一十一、Flume——Flume实时采集Linux中的Hive日志写入到HDFS中(亲测、附截图)
  • python 实现 AIGC 大模型中的概率论:生日问题的基本推导
  • YOLOv8算法改进【NO.87】引入上下文引导网络(CGNet)的Light-weight Context Guided改进C2_f
  • GPT-4V 在机器人领域的应用
  • Java基础语法之访问修饰限定符
  • 算法通关村第十八关 | 青铜 | 回溯
  • 蓝牙在物联网中的应用,相比WIFI和NFC的优势?