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

封装信号灯集相关API

由信号灯实现通信。

发送端send.c代码:

#include <myhead.h>
#include "./sem.h"
#define PAGE_SIZE 4096
int main(int argc, const char *argv[])
{
	int semid = semID_get(2);//创建2个信号灯

	key_t key = ftok("./",'U');
	if(key==-1)
	{
		perror("ftok");
		return -1;
	}

	int shmID = shmget(key,PAGE_SIZE,IPC_CREAT|0664);
	if(shmID==-1)
	{
		perror("shmget");
		return -1;
	}
	

	char *sendbuff = shmat(shmID,NULL,0);//映射出共享内存
	if(sendbuff==(void *)-1)
	{
		perror("shmat");
		return -1;
	}

	while(1)
	{
		P(semid,0);//申请0号灯资源
		printf("请输入你的信息:");
		fgets(sendbuff,PAGE_SIZE,stdin);
		sendbuff[strlen(sendbuff)-1]='\0';
		V(semid,1);//释放1号灯资源

		if(strcmp("quit",sendbuff)==0)
		{
			break;
		}

	}
	if(shmdt(sendbuff)==-1)
	{
		perror("shmat");
		return  -1;
	}

	if(shmctl(shmID,IPC_RMID,NULL)==-1)
	{
		perror("shmctl");
		return -1;
	}
	return 0;
}

接收端rev.c代码:

#include <myhead.h>
#include "./sem.h"
#define PAGE_SIZE 4096
int main(int argc, const char *argv[])
{

	int semid = semID_get(2);
	key_t key = ftok("./",'U');
	if(key==-1)
	{
		perror("ftok");
		return -1;
	}

	int shmID = shmget(key,PAGE_SIZE,IPC_CREAT|0664);
	if(shmID==-1)
	{
		perror("shmget");
		return -1;
	}
	

	char *revbuff = shmat(shmID,NULL,0);//只读
	if(revbuff==(void *)-1)
	{
		perror("shmat");
		return -1;
	}

	while(1)
	{
		P(semid,1);//申请1号灯资源
		printf("%s\n",revbuff);
		if(strcmp("quit",revbuff)==0)
		{
			break;
		}
		V(semid,0);//释放0号灯

	}

	return 0;
}

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 sem_INFO;

	printf("请输入编号为%d信号灯的值:",SEMno);
	scanf("%d",&sem_INFO.val);
	getchar();

	if(semctl(SEMid,SEMno,SETVAL,sem_INFO)==-1)
	{
		perror("semtal");
		return -1;
	}
	return 0;
}
//申请信号灯id,初始化信号灯,返回信号灯集的id
int semID_get(int SEMcount)
{
	key_t key = ftok("./",'Y');
	if(key==-1)
	{
		perror("key");
		return -1;
	}

	int SEMid;
	if((SEMid = semget(key,SEMcount,IPC_CREAT|IPC_EXCL|0664))==-1)
	{
		if(errno==EEXIST)
		{
			SEMid = semget(key,SEMcount,IPC_CREAT|0664);//已经存在直接打开即可
			return SEMid;
		}
		perror("semget");
		return -1;
	}
	int i;
	for(i = 0;i<SEMcount;i++)
	{
		init_semno(SEMid,i);//初始化信号灯
	}
	return SEMid;
}


int P(int SEMid,int SEMno)//申请资源
{
	
	struct sembuf SEM_op;
	SEM_op.sem_num = SEMno;//要申请资源的信号灯号
	SEM_op.sem_op = -1;//申请资源
	SEM_op.sem_flg = 0;//阻塞方式申请信号灯
	
	if(semop(SEMid,&SEM_op,1)==-1)//操作的灯个数
	{
		perror("semop P");
		return -1;
	}
	return 0;
}
int V(int SEMid,int SEMno)//释放资源
{
	
	struct sembuf SEM_op;
	SEM_op.sem_num = SEMno;//要申请资源的信号灯号
	SEM_op.sem_op = 1;//释放资源
	SEM_op.sem_flg = 0;//阻塞方式申请信号灯
	
	if(semop(SEMid,&SEM_op,1)==-1)//操作的灯个数
	{
		perror("semop V");
		return -1;
	}
	return 0;
}
int DEL_sem(int SEMid)
{
	if(semctl(SEMid,0,IPC_RMID)==-1)
	{
		perror("smectl");
		return -1;
	}
	return 0;
}

sem.h代码:

#ifndef _SEM_H_

#define _SEM_H_
//申请信号等集,返回信号灯集的id
int semID_get(int semno);//semno要设置灯的个数

//申请信号灯资源(value设置为0)
int P(int semID,int semno);//参数1:信号灯id,参数2灯的个数
//释放信号灯资源(value设置为1)
int V(int semID,int semno);
//删除信号灯集
int dele_sem(int semID);

#endif

运行结果:


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

相关文章:

  • 微服务即时通讯系统的实现(客户端)----(1)
  • CTF攻防世界小白刷题自学笔记13
  • Linux基础1
  • 什么时候需要复写hashcode()和compartTo方法
  • 界面控件Kendo UI for Angular中文教程:如何构建带图表的仪表板?(一)
  • 【Pikachu】目录遍历实战
  • 【JavaEE】深入浅出 Spring AOP:概念、实现与原理解析
  • HarmonyOS(AIP12 Beta5版)鸿蒙开发:选择条件渲染和显隐控制
  • 全志/RK安卓屏一体机:智能家居中控屏,支持鸿蒙国产化
  • Android studio设置国内镜像代理(HTTP Proxy)教程详解
  • PTA L1-027 出租
  • leedCode - - - 动态规划
  • 常见的深度学习模型总结
  • Elasticsearch7.15版本后新版本的接入
  • 三级_网络技术_54_应用题
  • FFmpeg 实现从设备端获取音视频流并通过RTMP推流
  • Prometheus+Grafana的安装和入门
  • 云上Oracle 数据库本地备份部署测试
  • Redis/ElaticSearch/kafka入门
  • 《经典图论算法》卡恩(Kahn)算法
  • 【电控笔记z27】相对位置控制(无前馈)
  • 【算法】递归、回溯、剪枝、dfs 算法题练习(N皇后、单词搜索、数独问题;C++)
  • Nginx: 反向代理和动静分离概述
  • 02. 开发前准备,Docker安装MySQL,Redis
  • SpringBoot优雅的封装不同研发环境下(环境隔离)RocketMq自动ack和手动ack
  • python实战二-筛选多个Excel中数据