您的位置:首页 > 健康 > 养生 > 快速排名优化_广州网站制作开发_优化生育政策_网站建设工作总结

快速排名优化_广州网站制作开发_优化生育政策_网站建设工作总结

2024/12/23 9:07:00 来源:https://blog.csdn.net/m0_74506452/article/details/144651100  浏览:    关键词:快速排名优化_广州网站制作开发_优化生育政策_网站建设工作总结
快速排名优化_广州网站制作开发_优化生育政策_网站建设工作总结

进程之间具有独立性. 其他的进程无法访问本进程的资源和内容.
那如果想要让进程访问一些某个进程内的内容, 我们该怎么做?

这时就需要通过进程间通信, 来完成两个进程之间的内容交互.
管道就是用来完成进程间通信的一种方式.

管道又分为匿名管道, 和命名管道.

管道

管道它允许两个进程之间的信息传递, 其中一个进程的输出直接作为另一个进程的输入.

管道是一种单向通信机制, 数据只能沿一个方向流动.

管道本质就是一个文件, 进程间通信就是让两个进程看见相同的空间 (文件)

并且管道都是位于内核区的, 而不是用户区

上面我们也提过, 管道只能单向通信, 即一个进程要么只能读, 要么只能写

如果想要实现两个进程都能进行"交流', 可以在创建一个管道, 这次读写的身份反过来.

匿名管道

匿名管道: 顾名思义这个管道文件没有名字

匿名管道通常用于父子进程之间进行通信

int pipefd[2]: 当创建好管道后, 会将管道读写端文件描述符返回

pipefd[0]: 管道读端的描述符.        pipefd[1]: 管道写端的描述符

返回值: 创建成功返回 0, 创建失败返回 -1

int main()
{//创建管道int pipefd[2]={0}; //0下标表示读取端,1下标表示写入端int n = pipe(pipefd);assert(n!=-1);pid_t id = fork();assert(id!=-1);if(id==0)//子进程, 构建单向通信{close(pipefd[1]);}//父进程写入,子进程读取close(pipefd[0]);return 0;
}

在上面的代码中, 我们先创建了匿名管道, 然后再创建子进程, 这样管道的两个文件描述符 pipefd[2] 就会被自动拷贝给子进程. 然后让父子进程分别关闭读端和写端.

当然, 上面的代码只实现了单项通信, 想实现双向通信就需要多创建一个管道.
既然管道就是一个文件, 那么读写数据也就是使用 read / write 函数.

int main()
{//创建管道int pipefd[2]={0}; //0下标表示读取端,1下标表示写入端int n = pipe(pipefd);assert(n!=-1);pid_t id = fork();assert(id!=-1);if(id==0)//子进程, 构建单向通信{close(pipefd[1]);char buffer[1024];while(1){ssize_t s = read(pipefd[0],buffer,sizeof(buffer)-1);if(s>0){buffer[s]=0;cout<<"father# "<<buffer<<endl;}else//read的返回值等于0代表父进程的管道文件已经close了{cout<<"写入结束,子进程退出";break;}}exit(0);}//父进程写入,子进程读取close(pipefd[0]);string str = "给子进程发信息";int count=0;char send_buffer[1024];snprintf(send_buffer,sizeof(send_buffer),"%s[%d]",str.c_str(),getpid());//往缓冲区里写入数据//写入到管道中write(pipefd[1],send_buffer,sizeof(send_buffer));// 关闭文件描述符, 释放资源close(pipefd[1]);pid_t ret = waitpid(id,NULL,0); // 等待子进程return 0;
}

匿名管道的特点: 

  • 管道常用于父子进程间的通信
  • 管道是面向字节流的服务
  • 管道是基于文件的,管道的生命周期随进程
  • 管道是单向通信的
  • 写快读慢,写满管道后不能再写了
  • 写慢读快,管道没有数据时,读端要等待
  • 写端关闭,读端会读到0,标识结束
  • 读端关闭,写端继续写会终止进程

命名管道

匿名管道必须在有血缘关系的进程间才能使用.
如果两个进程之间没有血缘关系, 可以通过创建命名管道来进行通信.

命名管道可以通过使用命令创建, 也可以在程序中使用系统调用函数来创建.

1. 使用命令创建

mkfifo filename

mkfifo 用于创建命名管道

filename 被创建出来的管道的名称

2. 通过函数调用创建

#include <sys/types.h>
#include <sys/stat.h>

int mkfifo(const char *pathname, mode_t mode);

int main()
{mkfifo("fifo", 0644); // 创建一个管道, 名称为 fiforeturn 0;
}

当命名管道存在以后, 使用就和匿名管道是类似的.

读端代码:写端代码:

string ipcpath = "./fifo.ipc";
int main()
{//client不用自己创建管道文件,只需获取文件即可int fd = open(ipcpath.c_str(),O_WRONLY);if(fd<0){perror("open");exit(1);}//通信过程string buffer;cout<<"please Enter message: ";getline(cin,buffer);write(fd,buffer.c_str(),buffer.size());close(fd);return 0;
}

命名管道打开的的规则:

  • 如果没有进程打开命名管道进行写操作, 那么尝试从命名管道读数据的进程将被阻塞
  • 如果没有进程打开命名管道进行读操作, 那么尝试向命名管道写数据的进程将被阻塞

进程可以在打开命名管道时设置非阻塞标志 (O_NONBLOCK) , 这样在没有对应读/写操作时, read()write()调用将立即返回, 而不是阻塞等待.

命名管道的使用, 和文件的使用是非常相似的, 会文件操作就会命名管道的使用.

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com