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

彩票网站怎么做赚钱吗竞价排名是什么意思

彩票网站怎么做赚钱吗,竞价排名是什么意思,自制网页设计网站,做暧暧视频免费视频中国网站📝前言: 这篇文章我们来讲讲Linux 进程间通信(三)——命名管道 🎬个人简介:努力学习ing 📋个人专栏:Linux 🎀CSDN主页 愚润求学 🌄其他专栏:C学习…

📝前言:

这篇文章我们来讲讲Linux 进程间通信(三)——命名管道

🎬个人简介:努力学习ing
📋个人专栏:Linux
🎀CSDN主页 愚润求学
🌄其他专栏:C++学习笔记,C语言入门基础,python入门基础,C++刷题专栏


这里写目录标题

  • 一,命名管道介绍
    • 1. 原理介绍
    • 2. 简单创建
    • 3. 简单使用
    • 4. 管道文件特殊的读写规则
    • 5. 命名管道删除
  • 二,使用示例
    • 错误和退出宏
    • 示例1
      • 思路
      • 代码
      • 运行
    • 示例2
      • 思路
      • 代码
      • 运行

一,命名管道介绍

之前我们介绍过了匿名管道,匿名管道通常用于有血缘关系的进程。那如果两个毫无关系的进程之间要进行通信,这时候就需要用到我们的命名管道。

1. 原理介绍

首先,想要进行进程间通信,就要让两个进程看到同一份资源!这份资源就是文件!
命名管道的原理和匿名管道基本相同,都是要让两个进程看到同一份文件。那两个没有血缘关系的进程是如何做到的呢?

在这里插入图片描述

  • 当两个进程打开同一路径下的同一个文件的时候,对应的文件描述符会被写入对应进程的文件描述符表中
  • 而对应文件的struct file其实是会被拷贝一份的(尽管两个struct file描述的都是c.txt文件,但是两个进程可能会在文件中有不同的读写位置不同的struct file就会记录)
  • 但是文件的 inode 和 文件内核缓冲区(这是文件在内存中真正的主体)是不会拷贝的,因为都是同一个文件的。
  • 即:因为路径具有唯一性,两个进程利用路径的唯一性看到了同一个文件(资源)。因为文件有文件名,所以叫做命名管道。

问题是,对于普通文件来说,IO会往磁盘刷新!
所以,OS提供了一种特殊的文件:管道文件,这种文件不会往磁盘刷新。这样两个进程就可以通过读写这个文件来实现通信!

2. 简单创建

我们用mkfifo来创建管道文件,命令和库函数同名

命令:
在这里插入图片描述
库函数:
在这里插入图片描述

  • 参数:(文件路径,创建文件时的权限)
  • 返回值:成功:0,失败:-1

示例(命令行创建):

mkfifo fifo.txt

在这里插入图片描述
这个p就代表是管道文件

示例(库函数创建):

#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
int main()
{int ret = mkfifo("fifo2.txt", 0666);if(ret == 0)std::cout << "创建管道文件fifo2.txt成功" << std::endl;return 0;
}

在这里插入图片描述
当命名管道创建好后,和普通文件的使用放个一模一样。先打开,然后再读写操作。

3. 简单使用

命令行输入:echo "hello world" > fifo.txt
结果:
在这里插入图片描述
就像被卡柱一样,直到我们cat fifo.txt才有反应:
在这里插入图片描述
在这里插入图片描述
这是因为,管道文件有特殊的读写规则。

4. 管道文件特殊的读写规则

管道文件的读写端必须都打开了才能工作,不然一段会端塞。

以上面的例子为例,

  • 当使用 echo "hello world" > fifo.txt 往管道写数据时,必须有另一个进程在管道的读端等待读取数据,否则写操作会被阻塞

  • 同理,如果先打开读端,但是写端没有打开,读端也会阻塞等待写端打开。

5. 命名管道删除

使用unlink
在这里插入图片描述
当然,命令行也可以用rm
在这里插入图片描述
系统调用删,常用于代码中

二,使用示例

错误和退出宏

  • 当一个操作错误时,C语言会设置对应的错误码在errno,我们可以通过perror来打印对应错误码的错误信息。
  • 如果我们想在打印错误信息后立刻终止程序,可以添加exit操作

上述两个操作,我们可以用一个宏 + do...while(0)来包装一下

#define ERR_EXIT(m) \
do { \perror(m); \exit(EXIT_FAILURE); \
} while(0)
  • do...while(0):只是为了提供一个能用于代码块包装的{}
  • 后续写代码时,我们直接调用ERR_EXIT(m)m为我们传入的字符串提示信息
  • 因为宏是要写到一行的,\是为了换行
  • EXIT_FAILURE 是标准库 <stdlib.h> 中已经定义的宏(通常值为 1

示例1

思路

重建两个进程,利用命名管道进行文件的拷贝:把file1.txt 的 内容拷贝到 file2.txt

基本思路:

  • 一个进程往命名管道里面写入file1.txt的内容
  • 另一个进程从命名管道读内容,写入file2.txt

代码

WriteN 文件:

#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <cstdlib>
#include <fcntl.h>
#include <unistd.h>using namespace std;#define ERR_EXIT(m)         \do                      \{                       \perror(m);          \exit(EXIT_FAILURE); \} while (0)int main()
{// 创建命名管道int m = mkfifo("tp", 0666);if (m < 0)ERR_EXIT("mkfifo"); // 代表mkfifo这个行为发生错误// 打开原有文件int infd = open("file1.txt", O_RDONLY);if (infd < 0)ERR_EXIT("open");// 打开命名管道int outfd = open("tp", O_WRONLY);if (outfd < 0)ERR_EXIT("open");// 把原有文件的内容输出到命名管道char buffer[1024];int n;while ((n = read(infd, buffer, sizeof(buffer))) > 0) // 当还读到有数据时{write(outfd, buffer, n);}close(infd);close(outfd);return 0;
}

ReadN文件:

#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <cstdlib>
#include <fcntl.h>
#include <unistd.h>using namespace std;#define ERR_EXIT(m)         \do                      \{                       \perror(m);          \exit(EXIT_FAILURE); \} while (0)int main()
{// 打开命名管道int infd = open("tp", O_RDONLY);if(infd < 0) ERR_EXIT("open");// 打开要写入的文件int outfd = open("file2.txt", O_CREAT | O_WRONLY | O_TRUNC, 0666);if (outfd < 0)ERR_EXIT("open");// 把命名管道的内容写到要拷贝到的文件char buffer[1024];int n;while((n = read(infd, buffer, sizeof(buffer))) > 0) // 当还读到有数据时{write(outfd, buffer, n);}close(infd);close(outfd);// 删除命名管道unlink("tp");return 0;
}

运行

一个终端先运行writer,另一个终端再运行reader,就完成了文件拷贝工作
在这里插入图片描述

示例2

思路

  • 利用命名管道建立一个服务段和客户端对话的窗口。
  • 客户端往命名管道里面写数据。
  • 服务段从命名管道里面读数据。

代码

comm.hpp文件:

#pragma once#include <string>
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>#define PATH "."
#define FILENAME "fifo"using namespace std;#define ERR_EXIT(m)         \do                      \{                       \perror(m);          \exit(EXIT_FAILURE); \} while (0)class NamedPipe
{
public:NamedPipe(string path, string name): _path(path), _name(name){_fifoname = _path + "/" + _name;int m = mkfifo(_fifoname.c_str(), 0666);if (m < 0)ERR_EXIT("mkfifo");cout << "mkfifo " << _fifoname << "sucess" << endl;}~NamedPipe(){int u = unlink(_fifoname.c_str());if (u < 0)ERR_EXIT("unlink");cout << "unlink " << _fifoname << "sucess" << endl;}private:string _path;string _name;string _fifoname;
};class Link // 服务端和用户端通过这个Link对象来进行对话
{
public:Link(const string& path, const string& name) // 这个构造只是为了把上面创建的命名管道的信息拿下来: _path(path), _name(name){_fifoname = _path + "/" + _name;cout << "Link " << _fifoname << " -> sucess" << endl;}void LinkForWrite(){// 当命名管道创建好了以后,就当做普通文件一样访问_fd = open(_fifoname.c_str(), O_WRONLY | O_TRUNC);if (_fd < 0)ERR_EXIT("open");cout << "Now you can write something to server " << endl;}void LinkForRead(){_fd = open(_fifoname.c_str(), O_RDONLY);if (_fd < 0)ERR_EXIT("open");cout << "Now you can read from client " << endl;}void Write(){while (true){string message;getline(cin, message);if(message == "quit"){break;}write(_fd, message.c_str(), message.size());}}void Read(){while (true){char buffer[1024];int n = read(_fd, buffer, sizeof(buffer) - 1);buffer[n] = '\0';if (n > 0){cout << buffer << endl;}else if (n == 0){cout << "cilent quit... now server quit" << endl;exit(EXIT_SUCCESS);}else{ERR_EXIT("read");}}}void Close(){close(_fd);}private:string _path;string _name;string _fifoname;int _fd;
};

client.cpp文件:

#include "comm.hpp"int main()
{Link Client(PATH, FILENAME);Client.LinkForWrite();Client.Write();Client.Close();
}

server.cpp文件

#include "comm.hpp"int main()
{// 创建命名管道// 构造时创建,进程结束时,自动析构NamedPipe fifo(PATH, FILENAME);Link Server(PATH, FILENAME);Server.LinkForRead();Server.Read();Server.Close();
}

Makefile文件:

.PHONY:all
all:client server
client:client.cppg++ -o $@ $^ -std=c++11
server:server.cppg++ -o $@ $^ -std=c++11.PHONY:clean
clean:rm -f client server
  • 伪目标all(不对应实际文件,仅用于执行命令),依赖于clientserver
  • make 执行all的时候,就会去执行clientserver目标

运行

在这里插入图片描述

在这里插入图片描述


🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!

http://www.dtcms.com/wzjs/457519.html

相关文章:

  • 建网站排名点击器免费版
  • 银川网站建设nx110百度网盘app手机版
  • 生物信息网站建设什么是seo搜索引擎优化
  • 户外媒体网站建设免费网站内容优化怎么去优化呢
  • 网上注册公司在哪个平台注册郑州百度关键词seo
  • 合伙做网站丈哥seo博客工具
  • 新办公司流程及资料优化大师卸载不了
  • 南通市建设局网站马建明搜狗营销
  • 网站建设 java域名注册服务网站查询
  • 怎么做区块链网站百度视频免费高清影视
  • 网站开发的三层架构网站发布与推广方式
  • 大学网站开发网球新闻最新消息
  • 西安可以做网站的如何做好推广
  • 制作网页链接的方法杭州小周seo
  • 网站建设好之后怎么上传东西苏州推广排名
  • 英国免费做网站seo咨询常德
  • 网站公司建设都招聘那些职位销售课程培训视频教程
  • 安徽网站推广营销设计如何提升网站搜索排名
  • 做网站团队的人员安排百度seo价格
  • 网站做外链免费创建个人博客网站
  • c2c网站的主要功能软文优化
  • WordPress url 数据表搜索引擎优化概述
  • 网络设计采用的方法和原则seo 工具分析
  • 企业培训平台太原seo排名收费
  • wordpress 图片站seo营销软件
  • 医学招聘网站开发区游戏推广代理加盟
  • 做目的旅游网站的百度网首页官网
  • 网站标签中的图片怎么做的企业域名查询
  • 濮阳网站建设在哪做seo怎么优化排名
  • Wordpress菜单的页面不显示武汉seo网站排名优化公司