电商门户网站建设方案wordpress自定义内容的小工具

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

电商门户网站建设方案,wordpress自定义内容的小工具,宠物网站建设总结,云龙主机 wordpress1.进程间通讯 1.1什么是通讯 进程具有独立性#xff08;每个进程都有自己的PCB,独立地址空间#xff0c;页表#xff09;但是要进行进程的通信#xff0c;通信的成本一定不低#xff0c;打破了独立性 进程间通信目的 数据传输#xff1a;一个进程需要将它的数据发送给…1.进程间通讯 1.1什么是通讯 进程具有独立性每个进程都有自己的PCB,独立地址空间页表但是要进行进程的通信通信的成本一定不低打破了独立性 进程间通信目的 数据传输一个进程需要将它的数据发送给另一个进程资源共享多个进程之间共享同样的资源。通知事件一个进程需要向另一个或一组进程发送消息通知它它们发生了某种事件如进程终止时要通知父进程。进程控制有些进程希望完全控制另一个进程的执行如Debug进程此时控制进程希望能够拦截另一个进程的所有陷入和异常并能够及时知道它的状态改变。 1.2为什么要有通讯 有时候需要多进程协同完成某种业务 cat file | grep hello //管道 1.3如何进行进程间通讯 两种通信方式 System V进程间通信——聚焦在本地通信共享内存信号量消息队列被主流排斥了POSIX进程间通信——-让通讯过程可以跨主机消息队列共享内存信号量互斥量条件变量读写锁管道———基于文件标准匿名管道命名管道 1.3.1管道 管道是Unix中最古老的进程间通信的形式。我们把从一个进程连接到另一个进程的一个数据流称为一个“管道” 该如何理解通讯的本质 要把一个进程的数据保留到一个地方让 另一个进程去读取这个地方必须要第三方提供不能是进程进程是具有独立性的。 第三方就是操作系统直接或间接为进程通讯提供”内存空间“ 要通讯的进程必须想看到一份公共的资源OS直接或间接提供 不同的通讯种类 本质就是上面所说的资源是OS中的哪一个模块提供的 如果i这个资源是文件体统提供的就叫这种通讯为管道 通讯的成本 1.把必须让不同的进程看到同一份资源2.然后通讯 任何一个文件都有自己的操作方法和属于自己的内核缓冲区struct Page{}缓冲区 此时我们再看父子进程他们两个是不是共同看到了同一份资源。是由文件管理系统提供的。 父进程 向文件缓冲区内写入子进程向文件缓冲区内读取这就是一个进程向文件中写数据另一个进程向文件中读数据 我们把这种通过文件的方式完成进程间的通讯的方式叫管道操作系统提的内核级文件称为管道文件本质就是文件。 具有缓冲区就是为了不让文件再写入磁盘再让另一个进程去磁盘里面读取这样效率太慢了需要在磁盘内存在该文件 可以直接让OS创建struct file只需要struct file的地址填入进程描述符表中就可以了然后父进程创建子进程拷贝文件描述符表父子进程就可以直接在内存中进行通讯。 得到管道是内存级文件不需要磁盘刷新 如何让两个进程看到同一个管道文件呢 fork创建子进程完成的。父子进程使用同一个文件描述符表 1.3.2匿名管道 前面我们说的管道文件没有名称所以称为匿名管道 pipe管道函数 创建成功返回0失败返回-1 int pipe(int pipefd[2]);//pipefd[2] 为输出型参数 调用pipe的时候操作系统内部帮你打开对应的文件读和写的方式,同一个文件打开两次得到两个文件描述符填充到你当前进程的文件描述符表中 然后把文件描述符表中的对应数组下标传给pipefd[2]这样就以读和写的方式分别打开了同一文件#include iostream #include unistd.h #include cassert #include sys/types.h #include sys/wait.h #include string #include cstdio #include cstringint main() {// 1.创建管道通讯int fds[2];int n pipe(fds);assert(n 0);std::cout fds[0]: fds[0] std::endl;std::cout fds[1]: fds[1] std::endl;// 父进程读取子进程写入// 2.fork()pid_t id fork();assert(id 0);if(id 0) //子进程{//子进程的通讯//子进程关闭读的描述符[0]close(fds[0]);//string msg hello,i am child!;const char *s 我是子进程我正在给你发消息;int cnt 0;while(true){char buffer[1024];//只有子进程能看到snprintf(buffer,sizeof(buffer),child-parent say:%s[%d][%d],s,cnt,getpid());// snprintf(buffer,sizeof(buffer),child-parent say:[%d][%d],cnt,getpid());write(fds[1],buffer,strlen(buffer)); //不用1\0只是在C语言中这是系统sleep(1);//细节我每隔1s写一次cnt ;}exit(0);}//父进程的通讯代码//父进程关闭写的描述符[1]close(fds[1]);while(true){char buffer[1024]; //只有父进程能看到//ssize_t s read(fds[0],buffer,sizeof(buffer)-1); //把读到的数据当作字符串来处理//这里用sizeofbuffer//read 函数返回的是读取的字节数如果读取成功则返回值大于 0。//在读取前需要清空 buffer 数组以避免读取到之前的残留数据。//在判断是否有数据可读时你使用了 strlen(buffer)-1这可能导致读取的数据长度为负数//因为 buffer 数组未初始化。应该使用 sizeof(buffer)。if(s 0) buffer[s] 0; //主动添加反斜杠0std::cout Get Message# buffer | My Pid: getpid() std::endl;//细节父进程没有sleep}n waitpid(id,nullptr,0);assert(n id);return 0;} //谁读谁写 fds[0]:3 —》下标0对应读取0对应嘴读 fds[1]:4 —》下标1对应写入1对应笔写 管道的四种情况 读慢写快 在进程通讯的时候故意让子进程写的慢,sleep了一下但当sleep的时间变长的时候父进程读取的时间也变长 那么在父进程读取前的时间他在干什么?他在读取read是一种阻塞如果管道中没有了数据读端在读默认会直接阻塞当前正在读取的进程 读快写慢 相反 如果让子进程不sleep,父进程sleep(500);让子进程不断向管道中写管道的总容量是有大小的固定大小 当写端向缓冲区写满的时候写端会进入阻塞等读端进行读取。缓冲区的数据不会被覆盖。 缓冲区的读写特点 当缓冲区有很多数据的时候看似是一行一行写入一行一行读取其实是以二进制的形式指定大小进行读取 写关闭读端读到0也会关闭。 当子进程写一条消息直接break这时写端的文件描述符已经关闭只有读端还在读。总会过一段时间将管道内的数据读完。 当读到0个字符的时候将读的管道也关闭读是为写作服务的没有了写读也没有意义。 读关闭写就没有意义了浪费资源所以OS会给写进程发信号终止写端 1.3.3总结管道的特征 1.管道的生命周期进程就是进程的周期 2.管道可以用来进行具有血缘关系的进程之间的进程通信常用于父子通讯。 3.管道是面向字节流的网络部分 4.半双工 —— 单向通讯特殊情况 5.互斥与同步机制——–对共享资源进行保护的方案 1.4命名管道 两个没有血缘关系进程之间的通讯。 命令行命令 mkfifo mkfifo name_pipe 出现以p开头的文件管道 这个文件的特点可以一个进程进行写入另一个进程从管道中读取 ls named_pipe    //一个终端写 cat named_pipe  //另一个终端读 这是命令行式的两进程之间的管道通讯.但是管道文件的内容大小为0 当打开同一个文件两次操作系统不会给我们创建两个struct file对象而是公用一个对象。这时候向这个文件写并不会保存到磁盘而是在内存让另一个线程去读取这不就是一个管道吗。 请问命名管道让把不同的进程看到同一文件呢 让不同的进程打开指定名称路径文件名唯一性的同一个文件。这就是命名管道的规则可以通过名字来标志唯一性的。匿名管道是通过继承继承地址来保证唯一性的 mkfifo函数创建有名管道 #include #include int mkfifo(constchar *filename, mode_t mode); open(constchar *path, O_RDONLY);//1 open(constchar *path, O_RDONLY | O_NONBLOCK);//2 open(constchar *path, O_WRONLY);//3 open(constchar *path, O_WRONLY | O_NONBLOCK);//4 尽量使用阻塞方式打开 特点 1有名管道可以使非亲缘的两个进程互相通信 2通过路径名来操作在文件系统中可见但内容存放在内存中 3 文件IO来操作有名管道 4 遵循先进先出规则 5 不支持leek操作 6 单工读写 注意事项 1 程序不能以O_RDWR(读写)模式打开FIFO文件进行读写操作而其行为也未明确定义因为如一个管道以读/写方式打开进程可以读回自己的输出同时我们通常使用FIFO只是为了单向的数据传递 2 第二个参数中的选项O_NONBLOCK选项O_NONBLOCK表示非阻塞加上这个选项后表示open调用是非阻塞的如果没有这个选项则表示open调用是阻塞的 3  对于以只读方式O_RDONLY打开的FIFO文件如果open调用是阻塞的即第二个参数为O_RDONLY除非有一个进程以写方式打开同一个FIFO否则它不会返回如果open调用是非阻塞的的即第二个参数为O_RDONLY | O_NONBLOCK则即使没有其他进程以写方式打开同一个FIFO文件open调用将成功并立即返回。 对于以只写方式O_WRONLY打开的FIFO文件如果open调用是阻塞的即第二个参数为O_WRONLYopen调用将被阻塞直到有一个进程以只读方式打开同一个FIFO文件为止如果open调用是非阻塞的即第二个参数为O_WRONLY | O_NONBLOCKopen总会立即返回但如果没有其他进程以只读方式打开同一个FIFO文件open调用将返回-1并且FIFO也不会被打开。 4.数据完整性,如果有多个进程写同一个管道使用O_WRONLY方式打开管道如果写入的数据长度小于等于PIPE_BUF4K那么或者写入全部字节或者一个字节都不写入系统就可以确保数据决不会交错在一起。 1.5实现命名管道的通讯 1.5.1comm.hpp #ifndef COMM_HPP #define COMM_HPP #include iostream #include sys/types.h #include sys/stat.h #include string.h #include cassert #include cerrno #include unistd.h #include fcntl.h#define NAMED_PIPE /home/lin/Desktop/Linux_learn/named_pipe/mypipe.linbool creatFifo(const std::string path) {umask(0);int n mkfifo(path.c_str(),0666);if(n 0) return true;else{std::cout errno: errno err string: strerror(errno) std::endl;return false;} }void removeFifo(const std::string path) {int n unlink(path.c_str());//assert不要乱用意料之中用assert,意料之外用if判断assert(n 0); //debbug时是有效的release的时候就没有了。//如果在release的时候这个n就没有被使用会walling ,加一个强制类型转换会避免报错(void)n;
}#endif 1.5.2client.cc #include comm.hppint main() {std::cout client begin std::endl;int wfd open(NAMED_PIPE,O_WRONLY);std::cout client end std::endl;if(wfd 0 ){exit(1); }//写char buffer[1024];while (true){std::cout Please Saying#;fgets(buffer,sizeof(buffer),stdin);//if(strlen(buffer)0) buffer[strlen(buffer) - 1] 0; ssize_t n write(wfd,buffer,strlen(buffer) );assert(n strlen(buffer));(void)n;}close(wfd);removeFifo(NAMED_PIPE);return 0; } 1.5.3server.cc #include comm.hppint main() {bool r creatFifo(NAMED_PIPE);assert®;(void)r;std::cout server begin std::endl;int rfd open(NAMED_PIPE,O_RDONLY);std::cout server end std::endl;if(rfd 0 ){exit(1); }//读取char buffer[1024];while(true){ssize_t s read(rfd,buffer,sizeof(buffer));if(s 0){buffer[s] 0;std::cout client-server# buffer;}else if(s 0){std::cout client quit,me too! std::endl;}else{std::cout err string strerror(errno) std::endl; }}close(rfd);removeFifo(NAMED_PIPE);return 0; }