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

彩票网站怎么做赚钱吗seo专业培训技术

彩票网站怎么做赚钱吗,seo专业培训技术,集团官方网站建设,惠州网站建设一般多少钱📝前言: 这篇文章我们来讲讲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/202480.html

相关文章:

  • wordpress imprezaseo咨询茂名
  • 旅游网站建设需求分析如何优化
  • 做个人网站怎么做宁波seo推广方式排名
  • 自己做的网站如何用手机去查看石景山区百科seo
  • 重庆seo优什么是网站推广优化
  • asp网站 模板推广之家
  • 移动电商网站开发需求文档百度搜索关键词设置
  • 西宁摄网站制作原版百度
  • 注销公司流程超详细优化师助理
  • 高端的网站建设公司域名注册阿里云
  • Spring做网站和什么网络推广是什么职业
  • 文昌品牌网站建设费用为什么不建议去外包公司上班
  • 盘锦网站制作肇庆百度快速排名
  • 两个人做类似的梦 网站seo新站如何快速排名
  • 温州建设集团网站建站平台哪个好
  • 遵义网站推广百度关键词排名突然没了
  • 辽宁自助网站建设价格企点qq官网
  • 福田蒙派克二手车天津关键词优化网站
  • 易企秀怎么做网站链接百度平台投诉人工电话
  • 可以做防盗水印的网站seo优化与推广招聘
  • 做彩票网站怎么样全国疫情又严重了
  • 网站建设三层架构实训报告自助建站系统软件
  • 怎样用编程语言做网站云搜索引擎入口
  • dede 分类信息网站 模板最常见企业网站公司有哪些
  • 网站链接锚文字怎么做北京网站优化排名推广
  • 小程序做网站百度推广管家
  • 做打折网站如何3天引流800个人技巧
  • 网站单页面制作怎么免费建公司网站
  • 有全部公司的网站自己建网站怎么推广
  • 延边住房和城乡建设局网站seo搜索优化待遇