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

网站开发都需要什么软件望京 网站开发

网站开发都需要什么软件,望京 网站开发,网站制作前的图片路径,王烨名字怎么样进程通信 进程为什么需要通信呢#xff1f;进程通信的技术背景进程通信本质 进程通信分类管道匿名管道pipe匿名管道原理管道特点 命名管道创建命名管道命名管道原理 System V IPC管道与 System V的区别共享内存函数ftok()shmget() shmat()shmdt()shmctl()删除共享内存System V… 进程通信 进程为什么需要通信呢进程通信的技术背景进程通信本质 进程通信分类管道匿名管道pipe匿名管道原理管道特点 命名管道创建命名管道命名管道原理 System V IPC管道与 System V的区别共享内存函数ftok()shmget() shmat()shmdt()shmctl()删除共享内存System V 代码演示管道和共享内存总结 进程为什么需要通信呢 虽然进程都有相对独立性但是还是需要进行互相通信的比如说QQ发消息、一个进程想要给另一个进程发送数据、几个进程之间想共享一份数据等等这些都需要进程进行通信。、 进程通信的技术背景 进程是有独立性的。虚拟地址空间页表 保证进程运行的独立性进程内核数据结构进程的代码和数据由于独立性的原因通信成本会比较高 进程通信本质 进程通信的前提首先需要让不同的进程看到同一块“内存”特定的结构组织的同一块“内存”不属于任意进程是在进程的共享代码段。 进程通信分类 管道 我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”。 # | 命令就是连接两个进程之间的管道命令 # who命令输出两行数据交给wc -l 进程统计行数输出。 who | wc -l 匿名管道pipe 功能创建一个无名管道 int pipe(int fd [2]) 参数 fd文件描述符数组其中fd[0]为读端fd[1]为写端。 返回值成功返回0失败返回错误代码。 使用fork创建父子进程进行通信来验证管道的原理 fork之后子进程会创建一份新的PCB并且会复制一份父进程的文件描述符数组像打开文件的信息管道等都只共享的一份。 下面这段代码实现了子进程写入管道父进程从管道读出这一功能 #includeiostream #includeunistd.h //#include string.h #includecstring #includecerrno #includecassert #includecstdlib #includesys/wait.h #includesys/types.h int main() {//利用fork让两个不的进程看到同一份资源int pipefd[2] {0};//1.创建匿名管道int n pipe(pipefd);if(n0) //创建管道失败{std::coutpipe error, errno : strerror(errno)std::endl;return 1;}std::coutpipefd[0]: pipefd[0]std::endl; //0读端std::coutpipefd[1]: pipefd[1]std::endl; //1写端//2. 创建子进程pid_t id fork();assert(id!-1);if(id 0) //子进程{//3.关掉不需要得fd实现让父进程读子进程写得功能close(pipefd[0]);//4.开始通信 --结合某种场景int cnt 0;while(true){char x X;write(pipefd[1],x,1);std::coutCnt: cntstd::endl;sleep(1);}close(pipefd[1]);exit(0);}//父进程//3. 关闭不需要的fd让父进程读子进程写close(pipefd[1]);//4.开始通信char buffer[1024];int cnt 0;while(true){int n read(pipefd[0], buffer, sizeof(buffer)-1);if(n0){buffer[n]\0;std::cout我是父进程child give me messages:bufferstd::endl;}else if(n0){std::cout我是父进程读到了文件结尾std::endl;break;}else{std::cout我是父进程读管道异常std::endl;break;}sleep(2);if(cnt5) break;}close(pipefd[0]);int status 0;waitpid(id, status, 0);std::cout sig: (status 0x7f) std::endl;sleep(20);return 0; }匿名管道原理 fork之后子进程会复制一份父进程的文件描述符指向父进程已经打开的文件资源等等。而用父进程创建匿名管道后会在内存中开辟一份空间为父子进程之间提供通信而父进程创建的这份资源会以fd的形式存在父进程的打开文件表中。子进程复制后子进程也能访问。 如下图 管道特点 管道是用来进行具有血缘关系的进程进行进程见通信。—常用于父子通信管道具有通过让进程间协同提供了访问控制。 写快读慢写满了不能再写了。写慢读快管道中没有数据的时候读必须等待写关读0标识读到了文件结尾。读关写继续写OS终止写进程。 管道提供的是面向流式的通信服务----面向字节流管道是基于文件的文件的生命周期是随进程的管道的生命周期是随进程的管道是单向通信属于半双工通信的特殊情况如果要进行全双工通信需要创建两个管道。 命名管道 管道匿名管道应用的一个限制是只能在具有共同祖先的进程间通信。 但是如果想在不相关的进程之间交换数据可以使用FIFO文件来做这项工作这就是命名管道一种特殊类型的文件。 创建命名管道 可以从命令行中创建管道p开头即为管道文件 mkfifo [filename] 可以使用函数创建命名管道 int mkfifo(const char* filename, mode_t mode) 第一个参数是创建管道的路径 第二个参数是管道读写的权限一般是0666 命名管道原理 首先命名管道是一个特殊的文件因此它可以被打开到内存但是不会将内存数据刷新到磁盘该文件在系统中具有唯一路径因此进程可以通过该路径找到管道文件进行通信。 下面实现一段功能父进程创建管道文件然后从管道读消息子进程从管道写消息。 //1.comm.hpp #ifndef _COMM_H_ #define _COMM_H_#includeiostream #includestring #includesys/types.h #includesys/stat.h #includeunistd.h #includestdlib.h #includefcntl.h #includecstring #include Log.hpp using namespace std;#define MODE 0666 #define SIZE 128string ipcPath ./fifo.ipc;#endif//2. Log.hpp #ifndef _LOG_H_ #define _LOG_H_#includeiostream #includectime#define Debug 0 #define Notice 1 #define Warning 2 #define Error 3const std::string msg[] {Debug,Notice,Warning,Error };std::ostream Log(std::string message, int level) {std::cout | (unsigned)time(nullptr) | msg[level] | message;return std::cout; }#endif//3.client.cxx #include comm.hppint main() {//1.获取管道文件int fd open(ipcPath.c_str(), O_WRONLY);if(fd0){perror(open);exit(1);}//2.ipc过程string buffer;while (true){coutPlease Enter Message Line :;std::getline(std::cin, buffer);write(fd, buffer.c_str(), buffer.size());}//3.关闭文件close(fd);return 0; }//4. server.cxx #include comm.hpp #includesys/wait.hstatic void getMessage(int fd) {char buffer[SIZE];while(true){memset(buffer, \0, sizeof(buffer));ssize_t s read(fd, buffer, sizeof(buffer)-1);if(s 0){cout[ getpid() ]client sat:bufferendl;}else if(s 0){//end of filecerr[ getpid() ]read end of file, client quit, server quit too!endl;break;}else{//read errorperror(read);break;}} }int main() {//1.创建管道文件if(mkfifo(ipcPath.c_str(), MODE)0){perror(mkfifo);exit(1);}Log(管道文件创建成功, Debug) step1endl;//2.正常文件操作int fd open(ipcPath.c_str(), O_RDONLY);if(fd0){perror(open);exit(2);}Log(打开管道文件成功,Debug) step 2endl;int nums 3;for(int i 0; i nums; i){pid_t id fork();if(id 0){//3.编写正常的通信代码getMessage(fd);exit(1);}}for(int i 0; inums;i){waitpid(-1, nullptr, 0);}//4.关闭文件close(fd);Log(关闭管道文件成功,Debug) step 3endl;unlink(ipcPath.c_str()); //通信完毕删除管道文件Log(删除管道文件成功, Debug) step 4endl;return 0; }System V IPC 共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程地址空间这些进程间的数据传递不再涉及到内核换句话说进程不再通过执行进入内核的系统调用来传递彼此的数据。 如下图是 System V的通信方式 该方式直接在内存里建立一块空间供进程通信进程AB都会在自己的页表上建立好虚拟地址到物理地址的映射因此只需访问自己空间的地址就可以实现进程间通信。 管道与 System V的区别 管道对应的公共资源是文件而文件是OS内核对应的数据结构需要操作系统维护因此需要系统调用来实现。而System V只需要在物理内存上申请一块空间而内存是用户空间里的内容用户可以不经过系统调用直接进行访问直接进行内存级的读写即可。 但是共享内存的提供者是OS因为OS要管理共享内存因为OS要先描述再组织-共享内存 共享内存快对应的共享内存的内核数据结构。 申请需要OS管理但是申请完了之后用户可以直接访问。 共享内存函数 ftok() 第0步 功能生成一个唯一的key供shmget使用生成共享内存段。 int ftok(const char* pathname, int proj_id); 参数 pathname必须是存在的、可访问的文件路径 proj_id至少是8bit的非0数字自己给定 返回值若生成成功返回唯一的key值。失败返回-1 shmget() 1 .第一步 功能用来创建共享内存 int shmget(key_t key, size_t size, int shmflg); 参数 key这个共享内存段的名字唯一id size共享内存的大小 shmfg由九个标志权限构成他们的用法和创建文件open使用的mode模式标志一样 返回值成功返回一个非负整数该段共享内存段的标识码类似于fd失败返回-1 说明shmfg参数的具体解释IPC_CREAT创建共享内存如果底层已经存在获取已存在的id并且返回如果不存在创建共享内存并返回IPC_EXCL 单独使用无意义和上面一起使用若底层不存在创建它并返回若底层存在出错返回。–若返回成功的一定是一个全新的shm shmat() 2.第二步 功能将共享内存段连接到进程地址空间在页表上生成映射 void shmat(int shmid, const void shmaddr, int shmflg) 参数 shmid共享内存标识 shmaddr指定连接的地址一般填nullptr shmflg它的两个可能取值是SHM_RND和SHM_RDONLY 返回值成功返回一个指针指向共享内存的第一个地址失败返回-1 说明shmflgshmaddr为NULL核心自动选择一个地址shmaddr不为NULL且shmflg无SHM_RND标记则以shmaddr为连接地址shmadd不为NULL且shmflg设置了SHM_RND标记则连接的地址会自动向下调整为SHMLBA的整数倍。公式shmaddr - (shmaddr % SHMLBA)shmflgSHM_RDONLY标识该连接操作用作只读共享内存 shmdt() 第3步 功能将共享内存点与当前进程脱离 int shmdt(const void* shmaddr) 参数 shmaddr由shmat返回的指针 返回值成功返回0 失败返回-1 注意将共享内存段与当前进程脱离不等于删除共享内存段 shmctl() 第四步 功能用来控制共享内存 int shmctl(int shmid, int cmd, struct shmid_ds *buf); 参数 shmid由shmget返回的共享内存标识码 cmd将要采取的动作 buf指向一个保存着共享内存的模式状态和访问权限的数据结构 返回值成功返回0失败返回-1 说明cmdIPC_STAT把shmid_ds结构中的数据结构设置为共享内存的关联值IPC_SET在进程有足够权限的前提下把共享内存的当前关联值设置为shmid_ds数据结构中的值IPC_RMID删除共享内存段 删除共享内存 首先这种内存共享方式当我们程序结束后如果代码不主动删除那么该内存不会被释放 我们可以使用代码删除、也可以手动删除手动删除使用如下命令即可。 注意key只有在创建的时候才有其他时候访问共享内存都是用shmid System V 代码演示 该功能为Server创建共享内存并删除。Cilentt使用该共享内存传输数据。 // Log.hpp #ifndef _LOG_H_ #define _LOG_H_#includeiostream #includectime#define Debug 0 #define Notice 1 #define Warning 2 #define Error 3const std::string msg[] {Debug,Notice,Warning,Error };std::ostream Log(std::string message, int level) {std::cout | (unsigned)time(nullptr) | msg[level] | message;return std::cout; }#endif//comm.hpp #pragma once#includeiostream #includecstdio #includeunistd.h #includesys/types.h #includesys/ipc.h #includesys/shm.h #includecassert #includeLog.hppusing namespace std; //不推荐#define PATH_NAME /home/xty #define PROJ_ID 0x66 #define SHM_SIZE 4096 //共享内存大小最好是4096的整数倍//shmClient.cc #include comm.hppint main() {key_t k ftok(PATH_NAME, PROJ_ID);if(k0){Log(creat key failed, Error) client key : k endl;exit(-1);}Log(creat key done, Debug) client key : k endl;//获取共享内存int shmid shmget(k, SHM_SIZE, 0);if(shmid 0){Log(create shm failed, Error) client key : k endl;exit(2);}Log( create shm success, Debug) client key : k endl;sleep(10);char* shmaddr (char *)shmat(shmid, nullptr, 0);if(shmaddr nullptr){Log( attach shm failed, Error) client key : kendl;exit(3);}Log( attach shm success, Debug) client key : kendl;sleep(10);// 使用//去关联int n shmdt(shmaddr);assert(n!-1);Log(detach shm success, Debug) client key : k endl;sleep(10);// client 要不要chmctl删除呢不需要return 0; }//shmServer.cc #include comm.hppstring TransToHex(key_t k) {char buffer[32];snprintf(buffer, sizeof(buffer), 0x%x, k);return buffer; }int main() {//1.创建公共的key值key_t k ftok(PATH_NAME, PROJ_ID);assert(k!-1);Log(create key done, Debug) server key : TransToHex(k) endl;//2.创建共享内存 --建议要创建一个全新的共享内存--通信的发起者int shmid shmget(k, SHM_SIZE, IPC_CREAT|IPC_EXCL|0666);if(shmid -1){perror(shmget);exit(1);}Log( create shm done, Debug) shmid : shmidendl;sleep(10);//3.将指定的共享内存挂接到自己的地址空间char * shmaddr (char *)shmat(shmid, nullptr, 0);Log(attach shm done, Debug) shmid : shmid endl;sleep(10);//通信的逻辑...//4.将指定的共享内存从自己的地址空间中 去 关联int n shmdt(shmaddr);assert(n!-1);(void)n;Log(deatch shm done, Debug) shmid : shmid endl;sleep(10);//5. 删除共享内存, IPC_RMID即便是有进程和当下的shm挂接依旧删除共享内存n shmctl(shmid, IPC_RMID, nullptr);assert( n!-1);(void)n;Log(delete shm done, Debug) shmid : shmidendl;return 0; }//makefile .PHONY:allall:shmClient shmServershmClient:shmClient.ccg -o $ $^ -stdc11 shmServer:shmServer.ccg -o $ $^ -stdc11.PHONY:clean clean:rm -f shmClient shmServer 管道和共享内存总结 管道通信的过程由键盘-自己定义的缓冲区-进程A-write给内核缓冲区-内核缓冲区给管道文件-管道给内核缓冲区-read读到进程B处-自己定义的缓冲区-打印到屏幕。 共享内存通信由键盘-自己定义的缓冲区-进程A-直接写入共享内存-进程B读贡献内存-到自己定义的缓冲区-屏幕。
http://www.zqtcl.cn/news/123620/

相关文章:

  • 赤峰网站建设flash教程网站都有哪些
  • 网站建设哪里学成品短视频app源码搭建
  • 网站可以自己做温州制作手机网站
  • 根河企业网站建设房地产如何做网站推广
  • 东莞个人网站建设南宁网站制作公
  • 网站推广seo是什么上海市人力资源网官网
  • 玉溪做网站的公司delphi xe10网站开发
  • 使用vue做的网站有哪些企业门为什么要建设门户网站
  • 上海移动云网站建设在门户网站上爆光怎么做
  • 网站建设开票内容百度浏览器广告怎么投放
  • 深圳公司网站建立小程序商店制作
  • 网站建设知识网犀牛云做网站多少钱
  • 东莞seo优化推广重庆做网络优化公司电话
  • 网站建设的设计思路高校建设网站的特色
  • 宁波网站建设八宝山做网站的公司
  • 哪里有网站建设多少钱网站建设哪家服务态度好
  • 白云区网站开发公司备案不关闭网站的方法
  • 男的做那个视频网站家用电脑可以做网站服务器
  • 网站建设的行业客户烟台市未成年思想道德建设网站
  • 设计个网站要多少钱鼓楼网站开发
  • 东莞外贸网站搭建制作北京app开发制作
  • 优化网站公司外包微信商城怎么开店
  • 网站设计的导航栏怎么做东莞seo网络优化
  • wordpress直接上传视频网站吗做网站软件
  • 电脑维修网站模板下载来个网站吧好人一生平安2021
  • 做公益选哪个网站好网站建设方案多少钱
  • 丰台做网站的公司vs2015 手机网站开发
  • 宝思哲手表网站qq官网登录入口网页版
  • 二手书网站开发设计太原建设网站的公司
  • 江门网站seo推广qq代挂网站建设