Day 6.有名信号量(信号灯)、网络的相关概念和发端

有名信号量

1.创建:

semget

 int semget(key_t key, int nsems, int semflg);

功能:创建一组信号量

参数:key:IPC对像的名字

           nsems:信号量的数量

            semflg:IPC_CREAT

返回值:成功返回信号量ID
              失败返回-1

2.销毁

semctl

 int semctl(int semid, int semnum, int cmd, ...);

功能:向信号灯发送命令

参数:semid:信号等的ID

           semnum:具体操作信灯的编号

           cmd: IPC_RMID    删除信号灯
                      SETVAL      设置信号量的值

返回值:成功返回0;失败返回-1;

初始化:

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) */
        };

3.申请信号量

4.释放信号量

semop

int semop(int semid, struct sembuf *sops, size_t nsops);

功能:对信号量完成操作

参数:semid:信号灯的ID

           sops:信号量操作的数组的首地址

           nsops:数组元素的个数

返回值:成功返回0;失败返回-1;

unsigned short sem_num;  /* semaphore number */        操作信号量的下标
         short          sem_op;   /* semaphore operation */     具体对信号量的操作(申请:-1  释放:+1)
         short          sem_flg;  /* operation flags */         SEM_UNDO

write.c

#include "head.h"

int main(void)
{
	key_t key;
	int shmid = 0;
	char *p = NULL;
	int semid = 0;
	int val[2] = {0, 1};

	key = ftok(".", 'a');   //生成一个key值
	if (key == -1)
	{
		perror("fail to ftok");
		return -1;
	}

	semid = semget(key, 2, IPC_CREAT | 0664);  //通过key值创建一组信号量
	if (semid == -1)
	{
		perror("fail to semget");
		return -1;
	}

	init_sem(semid, val, 2);    //封装函数,对两组信号量初始化

	shmid = shmget(key, 4096, IPC_CREAT | 0664);    //根据这个key值创建一个共享内存空间
	if (shmid == -1)
	{
		perror("fail to shmget");
		return -1;
	}

	p = (char *)shmat(shmid, NULL, 0);        //将地址p用射到共享内存空间中
	if (p == NULL)
	{
		perror("fail to shmat");
		return -1;
	}

	while(1)
	{
		sem_p(semid, 1);     //封装函数,释放写信号量
		gets(p);      //像这个内存空间中写入数据
		sem_v(semid, 0);     //封装函数,申请读信号量
		if (!strcmp(p,".quit"))
		{
			break;
		}
	}

	shmdt(p);   //解除映射

	shmctl(shmid, IPC_RMID, NULL);   //删除共享内存空间

	return 0;
}

read.c

#include "head.h"

int main(void)
{
	key_t key;
	int shmid = 0;
	char *p = NULL;
	int semid = 0;
	int val[2] = {0, 1};

	key = ftok(".", 'a');   //创建一个key值
	if (key == -1)
	{
		perror("fail to ftok");
		return -1;
	}

	semid = semget(key, 2, IPC_CREAT | 0664);  //通过key值创建一组信号量
	if (semid == -1)
	{
		perror("fail to semget");
		return -1;
	}

	init_sem(semid, val, 2);    //封装函数,对两组信号量初始化

	shmid = shmget(key, 4096, IPC_CREAT | 0664);    //根据这个key值创建一个共享内存空间
	if (shmid == -1)
	{
		perror("fail to shmget");
		return -1;
	}

	p = (char *)shmat(shmid, NULL, 0);    //将地址p映射到共享内存空间中
	if (p == NULL)
	{
		perror("fail to shmat");
		return -1;
	}

	while(1)
	{
		sem_p(semid, 0);   //封装函数,申请以个读信号量	
		printf("p = %s\n",p);   //打印内存空间中的数据
		if (!strcmp(p,".quit"))      
		{
			break;
		}
		sem_v(semid, 1);    //封装函数,释放一个写信号量
	}

	shmdt(p);   //解除映射

	shmctl(shmid, IPC_RMID, NULL);         //删除共享内存空间

	return 0;
}

sem.c

#include "head.h"

#if 0
union semun
{
	int val;
	struct semid_ds *buf;
	unsigned short *array;
	struct seminfo *__buf;
};
#endif    //这个共用体应放在头文件中

/*对信号等的灯的信号量进行初始化*/
int init_sem(int semid, int *parray, int len)
{
	union semun myun;
	int i = 0;
	int ret = 0;

	for (i = 0; i < len; ++i)
	{
		myun.val = parray[i];
		ret = semctl(semid, i, SETVAL, myun);
		if (ret == -1)
		{
			perror("fail to semctl");
			return -1;
		}
	}

	return 0;
}

/*申请信号灯的信号量*/
int sem_p(int semid, int num)
{
	int ret = 0;
	struct sembuf mybuf;

	mybuf.sem_num = num;
	mybuf.sem_op = -1;
	mybuf.sem_flg = SEM_UNDO;

	ret = semop(semid, &mybuf, 1);
	if (ret == -1)
	{
		perror("fail to semop");
		return-1;
	}

	return 0;
}

/*释放信号灯的信号量*/
int sem_v(int semid, int num)
{
	int ret = 0;
	struct sembuf mybuf;

	mybuf.sem_num = num;
	mybuf.sem_op = +1;
	mybuf.sem_flg = SEM_UNDO;

	ret = semop(semid, &mybuf, 1);
	if (ret == -1)
	{
		perror("fail to semop");
		return-1;
	}

	return 0;
}



网络

网络:

数据传输、数据共享

1.网络协议模型:

OSI协议模型(分层模型、下一层为上一层提供服务)

应用层:实际发送的数据

表示层:发送的数据是否要加密

会话层:是否建立会话链接

传输层:数据传输的方式(数据报、流式)

网络层:数据的路由(如何从一个局域网到达另一个局域网)  依赖于IP地址

数据链路层:局域网下如何通信

物理层:物理介质的链接

TCP/IP协议模型

应用层:决定传输的数据

传输层:决定传输的法方式

网络层:数据如何从一台主机到达另一台主机

网络接口层:物理介质的链接

应用层:

HTTP        超文本传输协议

HTTPS        加密的超文本传输

FTP        文本传输协议

TFTP        简单文本传输协议

SMTP        邮件传输协议

MQTT

TELNET        

传输层:
UDP        用户数据报协议

特点:

1、实现机制简单

2、资源开销小

3、不安全不可靠

TCP        传输控制协议

特点:

1、实现机制复杂(三次挥手)

2、资源开销大

3、安全可靠(四次挥手)

网络层:
IPV4

IP地址:唯一标识网络中一台主机的标号

IP地址:网络位 + 主机位

子网掩码:用来标识IP地址的网络位和主机位

                子网掩码是1的部分表示IP地址的网络位

                子网掩码是0的部分表示IP地址的主机位

网段号:网络位不变,主机位全为0,表示网段号

广播地址:网络位不变,主机位全为1,表示广播地址

IP地址的类型:
A类

1.0.0.0-126.255.255.255

子网掩码:255.0.0.0

管理超大规模网络

私有IP地址:10.0.0.0 - 10.255.255.255 

B类

128.0.0.0-191.255.255.255

子网掩码:255.255.0.0

管理大中性规模网络

私有IP地址:172.16.0.0 - 172.31.255.255

C类

192.0.0.0-223.255.255.255

子网掩码:255.255.255.0

管理中小型规模网络

私有IP地址:192.168.0.0 - 192.168.255.255

D类

224.0.0.0-239.0.0.0

用于组播

E类

240.0.0.0-255.255.255.255

用于实验

2.UDP编程:

socket套接字编程:

1、发端:

1)socket

 int socket(int domain, int type, int protocol);

功能:创建一个用来通信的文件描述符

参数:domain:使用的协议族        AF_INET(IPV4协议族)

           type:套接字类型

                SOCK_STREAM:流式套接字
                SOCK_DGRAM:数据报套接字
                SOCK_RAW:原始套接字

             protocol:协议
                           默认为0

返回值:成功返回文件描述符;失败返回-1;

2)sendto

 ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                      const struct sockaddr *dest_addr, socklen_t addrlen);

功能:利用套接字向指定地址发送数据信息

参数:sockfd:套接字的文件描述符

buf:发送数据空间的首地址

len:发送数据的长度

flags:属性默认位0

dest_addr:目的地址信息存放的空间首地址

addrlen:目的地址的长度

返回值:成功返回实际发送的字节数;失败返回-1;

struct sockaddr_in {
            sa_family_t    sin_family; /* address family: AF_INET */
            in_port_t      sin_port;   /* port in network byte order */
            struct in_addr sin_addr;   /* internet address */
        };

        /* Internet address. */
        struct in_addr {
            uint32_t       s_addr;     /* address in network byte order */
        };

3)inet_addr

in_addr_t inet_addr(const char *cp);

功能:将字符串IP地址类型转换成内存IP地址

4)htons

uint16_t htons(uint16_t hostshort);

功能:将本地字节序转换成网络的大端字节序

#include "head.h"

int main(void)
{
	int sockfd = 0;
	struct sockaddr_in recvaddr;
	ssize_t nsize = 0;
	char tmpbuff[1024] = {0};

	fgets(tmpbuff, sizeof(tmpbuff), stdin);
	/* 创建用来通信的UDP套接字 */
	sockfd = socket(AF_INET, SOCK_DGRAM, 0);  //使用IPV4协议族 和数据报套接字
	if (-1 == sockfd)
	{
		perror("fail to socket");
		return -1;
	}
	/* 对方接收方地址赋值 */
	recvaddr.sin_family = AF_INET;  //
	recvaddr.sin_port = htons(50000);  //
	recvaddr.sin_addr.s_addr = inet_addr("192.168.149.1");  //
	/* 发送信息 */
	nsize = sendto(sockfd, tmpbuff, strlen(tmpbuff), 0, (struct sockaddr *)&recvaddr, sizeof(recvaddr));  //
	if (-1 == nsize)
	{
		perror("fail to sendto");
		return -1;
	}

	printf("成功发送%ld字节!\n",nsize);

	close(sockfd);

	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

职场中的团队合作:如何建立高效的团队协作

在职场中&#xff0c;团队合作是至关重要的。一个高效的团队可以协同工作&#xff0c;共同实现目标&#xff0c;提高工作效率&#xff0c;创造出卓越的成果。然而&#xff0c;建立一个高效的团队并不容易&#xff0c;需要团队成员之间的良好沟通、相互信任和合作。本文将分享一…

Java核心技术卷1——运算符 每日笔记

3.5 运算符 运算符用于连接值。 3.5.1算数运算符 在Java中&#xff0c;使用算术运算符、-、*、/表示加、减、乘、除运算。 当参与/运算的两个操作数都是整数时&#xff0c;表示整数除法&#xff1b; 否则表示浮点数除法。 整数的求余&#xff08;取模&#xff09;操作用%表示…

Laravel Octane 和 Swoole 协程的使用分析二

又仔细研究了下 Octane 源码和 Swoole 的文档&#xff0c;关于前几天 Laravel Octane 和 Swoole 协程的使用分析中的猜想&#xff0c;得到进一步验证&#xff1a; Swoole 的 HTTP Server 启动后会创建一个 master 进程和一个 manager 进程&#xff1b;master 进程又会创建多个…

《UE5_C++多人TPS完整教程》学习笔记26 ——《P27 在线会话测试(Testing An Online Session)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P27 在线会话测试&#xff08;Testing An Online Session&#xff09;》 的学习笔记&#xff0c;该系列教学视频为 Udemy 课程 《Unreal Engine 5 C Multiplayer Shooter》 的中文字幕翻译版&#xff0c;UP主&#xff0…

山海鲸可视化软件实战:如何制作一个高效的商品销售数据看板

作为一名数据分析师&#xff0c;我经常需要通过各种工具将数据转化为有价值的信息&#xff0c;为公司的决策提供支持。最近&#xff0c;我使用山海鲸可视化软件制作了一个商品销售数据看板&#xff0c;山海鲸可视化是一款可以免费可视化编辑、免费私有化部署的产品。下面&#…

6_怎么看原理图之协议类接口之LCD笔记

首先想一想再前几篇文章讲的协议类的前提 1、双方约定好通信的协议 2、双方满足一定的时序要求 以上第二点又有一些要求&#xff1a; 1&#xff09;弄清2440在这个通信协议中&#xff0c;能设置哪些时序的值&#xff0c;这些值的含义是什么——2440手册 2&#xff09;弄清楚这…

一文详解:Open SSL

Open SSL是 SSL (传输层安全)和 TLS (传输层安全)协议的健壮的开源实现。这些加密协议被广泛用于保护计算机网络上的通信&#xff0c;通过在两个通信应用程序之间提供隐私和数据完整性。从更实际的角度来说&#xff0c;OpenSSL 是一个工具包&#xff0c;其中包含各种命令行实用…

学习JAVA的第十四天(基础)

目录 Collection集合 迭代器遍历 增强for遍历 Lambda表达式遍历 List集合 遍历 数据结构 栈 队列 数组 链表 前言&#xff1a; 学习JAVA的第十三天 Collection集合 Collection的遍历方式&#xff1a; 迭代器&#xff08;不依赖索引&#xff09;遍…

当磁盘无法读取时,这样做能拯救你的数据!

一、遭遇磁盘无法读取的困境 在现代社会中&#xff0c;磁盘已成为我们存储和传输数据的重要工具。然而&#xff0c;当磁盘突然无法读取时&#xff0c;我们可能会面临数据丢失的风险&#xff0c;这无疑是一个令人头疼的问题。磁盘无法读取可能表现为电脑无法识别磁盘、磁盘在读…

基于yolov5的水果新鲜度检测系统,可进行图像目标检测,也可进行视屏和摄像检测(pytorch框架)【python源码+UI界面+功能源码详解】

功能演示&#xff1a; 基于yolov5的水果新鲜度检测系统&#xff0c;系统既能够实现图像检测&#xff0c;也可以进行视屏和摄像实时检测_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于yolov5的水果新鲜度检测系统是在pytorch框架下实现的&#xff0c;这是一个完整的…

opengl日记23-opengl文字渲染-渐变色-教程示例

Author: wencoo Blog&#xff1a;https://wencoo.blog.csdn.net/ Date: 23/02/2024 Email: jianwen056aliyun.com Wechat&#xff1a;wencoo824 QQ&#xff1a;1419440391 Details:文章目录 目录正文 或 背景 效果展示 目录 正文 或 背景 前些天发现了一个巨牛的人工智能学习…

华为HQoS配置案例

HQoS基于层次化调度&#xff0c;cpe上支持三级队列&#xff1a; level3流队列&#xff1a;每个用户的同类业务是一个业务流&#xff0c;针对每个用户不同的业务流进行队列调度&#xff0c;流队列一般与业务类型对应&#xff08;EF、AF、BE等&#xff09;。 level2用户队列&…

适用于 Windows 的7大数据恢复软件解决方案

数据丢失是数字世界中令人不快的一部分&#xff0c;它会在某一时刻影响许多计算机用户。很容易意外删除一些重要文件&#xff0c;这可能会在您努力恢复它们时带来不必要的压力。幸运的是&#xff0c;数据恢复软件可以帮助恢复已删除的文件&#xff0c;即使您没有备份它们。以下…

玩转小米:如何取消王者荣耀微信双开默认选择

文章目录 💢 问题 💢🏡 演示环境 🏡💯 解决方案 💯💢 问题 💢 当我们在手机上安装了多个微信(分身)后,在一些软件(例如王者)使用微信登入时会出现让们选择使用哪个微信进行登入,但是有时候我们不小心设置了默认某一个微信登入后,下次就无法出现选择页面…

Codesys 位置式PID闭环控制系统(PID+PWM控制无刷电机)

有关Codesys位置式PID算法公式和源代码,请参考下面文章链接: 1、Codesys位置式PID https://rxxw-control.blog.csdn.net/article/details/131591254https://rxxw-control.blog.csdn.net/article/details/1315912542、博途PLC PWM输出控制 https://rxxw-control.blog.csdn.…

JavaScript 闭包:让你更深入了解函数和作用域

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Mybatis框架相关问题

HashMap相关问题 部分示例代码 Mybatis框架相关问题 一、MyBatis框架是如何实现分页的&#xff1f;二、MyBatis框架里面的缓存机制是怎么回事&#xff1f;一级缓存二级缓存 一、MyBatis框架是如何实现分页的&#xff1f; 分页分为两种&#xff1a; 逻辑分页&#xff1a;将所…

直播美颜SDK开发指南:构建个性化的主播美颜工具

本篇文章&#xff0c;小编将带您深入了解如何构建个性化的主播美颜工具&#xff0c;从而为用户提供更优质的直播体验。 一、美颜技术概述 在开始SDK的开发之前&#xff0c;我们首先需要了解美颜技术的基本原理。美颜技术通常包括肤色检测、人脸检测、特征点定位、滤镜处理等步…

C++ 使用libmodbus通信示例

代码示例 #include <future> #include <iostream> #include <thread>#include <modbus.h>// 寄存器数量 #define TEST_MAX_REGISTERS 100 // 读取寄存器数量 #define TEST_MAX_READ 5int main() {// C 异步auto&& f1 std::async(std::launch…

绘图设计:用Draw.io绘制图形技巧大全(含统一建模语言UML模板)

一、常见UML模板 1.流程图 2.用例图 include是包含关系&#xff0c;extend是扩展关系 简而言之&#xff0c;include是子集指向父集&#xff1b;而extend是扩展用例指向基础用例&#xff08;基础用例可以理解为系统核心功能&#xff0c;扩展用例是可选的&#xff0c;不是必须…