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

完全网络营销网站株洲seo优化

完全网络营销网站,株洲seo优化,中国菲律宾汇率换算,福建网站开发公司电话1.进程间通信 进程间通信的背景#xff1a; 进程之间是相互独立的#xff0c;进程由内核数据结构和它所对应的代码和数据#xff0c;通信成本比较高。 进程间通信目的#xff1a; 数据传输#xff1a;一个进程需要将它的数据发送给另一个进程 资源共享#xff1a;多个进程…1.进程间通信 进程间通信的背景 进程之间是相互独立的进程由内核数据结构和它所对应的代码和数据通信成本比较高。 进程间通信目的 数据传输一个进程需要将它的数据发送给另一个进程 资源共享多个进程之间共享同样的资源。 通知事件一个进程需要向另一个或一组进程发送消息通知它它们发生了某种事件如进程终止时要通知父进程。 进程控制有些进程希望完全控制另一个进程的执行如Debug进程此时控制进程希望能够拦截另一个进程的所有陷入和异常并能够及时知道它的状态改变。 进程间通信本质 进程间通信的前提就是让不同的进程看到相同的一份“内存”这块“内存”不属于任何一个进程属于操作系统。 2.进程间通信的方式 1.管道 匿名管道 命名管道 2.System V通信 多进程 单机通信 3.POSIX 通信 多线程 网络结构在这里不讲 3.管道讲解 1.管道分类匿名管道命名管道。 2.什么是管道         管道是一种古老的传输资源的方式是UNIX中过来的传输方式是从一个进程传递到另一个进程的方法。管道是单向通信的传输的都是资源不能同时完成双向通信。 3.实现原理 匿名管道   如何做到不同进程看到相同的内存呢 fork()函数让具有血缘关系的进程进行进程间通信常用于父子进程。 创建管道文件int pipe(int pipefd[2]); 具体实现看代码 #include iostream #include cstdio #include cassert #include cstring #include sys/types.h #include sys/wait.h #include unistd.husing namespace std;int main() {int pipefd[2]{0}; pipefd[0(嘴巴读书)]: 读端 , pipefd[1(钢笔写)]: 写端int n pipe(pipefd);assert(n ! -1); // debug assert, release assert(void)n;#ifdef DEBUGcout pipefd[0]: pipefd[0] endl; // 3cout pipefd[1]: pipefd[1] endl; // 4#endifpid_t idfork();if(id0){close(pipefd[1]);char buff[1024*8];while(true){ssize_t s read(pipefd[0], buff, sizeof(buff) - 1);if(s0){buff[s] 0;cout child get a message[ getpid() ] Father# buff endl;}else{cout writer quit(father), me quit!!! endl;break;}}close(pipefd[0]);//关闭文件可以不用exit(0);//return 0;}else if(id0){close(pipefd[0]);string message 我是父进程我正在给你发消息\n;int count 0;char send_buffer[1024 * 8];while(true){//构建一个变化的字符串snprintf(send_buffer, sizeof(send_buffer), %s[%d] : %d,message.c_str(), getpid(), count);//写到一个字符串write(pipefd[1], send_buffer, strlen(send_buffer));if(count5){coutcountendl;break;}}close(pipefd[1]);//进程等待//int status;pid_t ret waitpid(id,NULL,0);cout id : id ret: ret endl;assert(ret 0); (void)ret;}return 0; } 结论 管道是用来进行具有血缘关系的·进程实现进程间通信--常用于父子进程。具有让进程间协同通信提供了访问控制。提供面向流的听信服务面向字节流的服务。管道是基于文件的文件的生命周期是基于进程的所以管道的生命周期是基于进程的。管道是单向通信的就是半双工通信的一种特殊形式。 如果写得快读得慢则写满管道之后不再写入。 如果写的慢读得快则管道没有数据是则停下来等待。 如果写入端关闭则读到文件末尾结束 关闭读则OS会关闭写进程。 命名管道 管道应用的一个限制就是只能在具有共同祖先具有亲缘关系的进程间通信。如果我们想在不相关的进程之间交换数据可以使用FIFO文件来做这项工作它经常被称为命名管道。命名管道是一种特殊类型的文件。 命名管道的创建 直接在命令行上创建mkfifo filename 也可以在程序中创建int mkfifo(const char *filename,mode_t mode); 第一个参数为文件名第二个为权值 创建命名管道 int main(int argc, char *argv[]) {mkfifo(p2, 0644);return 0; } 匿名管道与命名管道之间的区别 匿名管道由pipe函数创建并打开。命名管道由mkfifo函数创建打开用open。FIFO命名管道与pipe匿名管道之间唯一的区别在它们创建与打开的方式不同一但这些工作完。成之后它们具有相同的语义。 读写规则 如果当前打开操作是为读而打开FIFO时         O_NONBLOCK disable阻塞直到有相应进程为写而打开该FIFO         O_NONBLOCK enable立刻返回成功 如果当前打开操作是为写而打开FIFO时         O_NONBLOCK disable阻塞直到有相应进程为读而打开该FIFO         O_NONBLOCK enable立刻返回失败错误码为ENXIO 代码实现 #ifndef _COMM_H_ #define _COMM_H_ //公共文件 #include iostream #include cstdio #include string #include cstring #include unistd.h #include sys/types.h #include sys/stat.h #include sys/wait.h #include fcntl.h #include log.hpp using namespace std;#define MODE 0666 #define SIZE 128string ipcPath ./fifo.ipc;#endif //日志文件#include iostream #include ctime #include string#define Debug 0 #define Notice 1 #define Warning 2 #define Error 3//创建方法 const 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//读文件 #include comm.hpp #include log.hppstatic void getMessage(int fd) {char buffer[SIZE];while(true){memset(buffer,\0,sizeof buffer);int sread(fd,buffer,sizeof(buffer)-1);if(s0){cout [ getpid() ] client say buffer endl;//还有文件}else if(s0){cerr [ getpid() ] read end of file, clien quit, server quit too! endl;//读到文件末尾break;}else if(s0){perror(read s);break;}} } int main() {int idmkfifo(textfifo.txt,0666);//创建命名管道文件if(id0)//创建失败{perror(mkfifo id);return 0;}Log(创建管道文件成功, Debug) step 1 endl;//打印日志int fd open(ipcPath.c_str(), O_RDONLY);//打开文件以读的方式if (fd 0){perror(open);exit(2);}Log(打开管道文件成功, Debug) step 2 endl;int nums3;for(int i0;inums;i){pid_t idfork();if(id0){getMessage(fd);exit(1);}}//父进程阻塞等待for(int i0;inums;i){waitpid(-1, nullptr, 0);}close(id);//关闭文件Log(关闭文件Debeg) step 3 endl;unlink(ipcPath.c_str()); //删除文件Log(删除文件Debeg) step 4 endl;return 0; }//写文件 #include comm.hpp #include log.hppint main() {int idopen(ipcPath.c_str,O_WRONLY);//获取文件if(id0){perror(open file);}string buffer;while(true){cout Please Enter Message Line : ;std::getline(std::cin, buffer);//写文件write(id,buffer.c_str(),buffer.size());}close(id);//关闭//unlink(id);return 0; } 结论双方进程可以看到同一份文件该文件一定在系统路径中路径具有唯一性管道文件可以被打开但是不会将内存中的数据刷新到磁盘中。且有名字。 3.System V 通信 共享内存共享内存区是最快的IPC形式。共享内存是在物理内存上申请一块空间再让两个进程各自在页表建立虚拟地址和这块空间的映射关系。这样两个进程看到的就是同一份资源这一份资源就叫做共享内存。 原理 共享内存的提供者是操作系统操作系统通过先描述再组织的方式管理共享内存。 共享内存共享内存块对应的共享内存的内核数据结构。 两个进程创建共享内存需要以下步骤 创建共享内存将两个进程关联到共享内存取消两个进程和共享内存的关联删除共享内存 注意 前两个步骤是为了让两个进程实现通信后面两个步骤是释放共享内存空间要不然就会内存泄漏了。与我们之前用的malloc是类似的。 创建共享内存所需要的函数 1.ftok——获取一个共享内存的唯一标识符 函数key_t ftok(const char *pathname, int proj_id); 功能获取一个共享内存的唯一标识符 key 参数 pathname 文件名 ;proj_id 只有是一个非0的数都可以 . 返回值成功返回key;失败返回 -1 2..shmget——创建共享内存 函数int shmget(key_t key, size_t size, int shmflg); key:传入ftok函数获取的共享内存唯一标识符 size:共享内存的大小页4kb的整数倍 shmflg:权限由9个权限标准构成 这里介绍两个选项 IPC_CREAT 如果底层存在这个标识符的共享内存空间就打开返回不存在就创建 IPC_EXCL 如果底层存在这个标识符的共享内存空间就出错返回 两个选项合起来用就可以穿甲一个权限的共享内存空间 返回值 成功返回共享内存标识码值给用户看的失败返回-1. 3.shmat——将共享内存空间关联到进程地址空间 函数void *shmat(int shmid, const void *shmaddr, int shmflg); 功能 将共享内存空间关联到进程地址空间 参数 shmid:共享内存标识符 shmaddr:指定连接地址。 shmfig:两个可能取值是SHM_RND和SHM_RDONLY 返回值 成功返回一个指针虚拟地址空间中共享内存的地址是一个虚拟地址失败返回-1 说明 shmaddr为NULL核心自动选择一个地址。 shmaddr不为NULL且shmflg无SHM_RND标记则以shmaddr为连接地址。 shmaddr不为NULL且shmflg设置了SHM_RND标记则连接的地址会自动向下调整为SHMLBA的整 数倍。公式shmaddr -(shmaddr % SHMLBA) shmflgSHM_RDONLY表示连接操作用来只读共享内存。 4.shmdt——取消关联 函数int shmdt(const void *shmaddr); 功能 取消共享内存空间和进程地址空间的关联参数 shmaddr:共享内存的起始地址shmat获取的指针返回值 成功返回0失败返回-1 5.shmctl——控制共享内存 函数int shmctl(int shmid, int cmd, struct shmid_ds *buf); 功能 控制共享内存 参数 shmid:共享内存标识符 cmd:命令有三个 IPC_STAT: 把shmid_ds结构中设置为共享内存当前关联值 IPC_SET: 把共享内存的当前关联值设置为shmid_ds数据结构中的值 IPC_RMID:删除共享内存段 buf:指向一个报错这共享内存的模式状态和访问权限的数据结构 返回值 成功返回0失败返回-1。 共享内存的特性 对于共享内存来说它与管道有不同的特性导致共享内存不同的使用方法 1.管道需要使用系统接口来调用但是共享内存可以不用经过系统调用直接可以访双方进程如果要进行通信直接进行内存级的读和写即可。共享内存实在堆栈之间的区域的堆栈相对而生中间区域为共享内存不用经过操作系统。 共享内存是最快的为什么呢 因为如果是管道需要从键盘写入然后再拷贝到自己定义的缓冲区中然后再次拷贝到内存中再从内存中拷贝到用户级缓冲区中最后再拷贝到屏幕中需要经历最少4词的拷贝过程。 共享内存直接面向用户所以从键盘中输入的内容直接进入到内存中然后经过内存到达显示器中最少只有2次拷贝所以他的速度是最快的。 对于共享内存的理解 为了进行进程间通信需要让不同的进程看到相同的一份资源所以之前的管道本质都是优先解决一个问题让不同的进程看到同一份资源 让不同的进程看到相同的内存带来了有些时序问题造成数据不一致问题。 结果 我们把多个进程执行流看到的同一份资源称为临界资源。 我们把自己的进程访问临界资源的代码称为临界区。 为了更好地进行临界区的保护可以让多执行流在任何时刻都只有一个进程进入临界区。即互斥 原子性要么不做要么做完没有中间状态即为原子性 所以多个执行流互相运行的时候互相干扰主要是我们不加保护的访问了相同的资源临界资源在非临界区多个执行流是互不干扰的。 代码演示 #pragma once#include iostream #include cstdio #include unistd.h #include sys/types.h #include sys/ipc.h #include sys/shm.h #include cassert #include Log.hppusing namespace std; //不推荐#define PATH_NAME /home/SSS//环境变量 #define PROJ_ID 0x66 #define SHM_SIZE 4096 //共享内存的大小最好是页(PAGE: 4096)的整数倍 #define FIFO_NAME ./fifo //创建一个管道形成访问控制 class Init { public:Init(){umask(0);int n mkfifo(FIFO_NAME, 0666);assert(n 0);(void)n;Log(create fifo success,Notice) \n;}~Init(){unlink(FIFO_NAME);Log(remove fifo success,Notice) \n;} };#define READ O_RDONLY #define WRITE O_WRONLYint OpenFIFO(std::string pathname, int flags) {int fd open(pathname.c_str(), flags);assert(fd 0);return fd; }void Wait(int fd) {Log(等待中...., Notice) \n;uint32_t temp 0;ssize_t s read(fd, temp, sizeof(uint32_t));assert(s sizeof(uint32_t));(void)s; }void Signal(int fd) {uint32_t temp 1;ssize_t s write(fd, temp, sizeof(uint32_t));assert(s sizeof(uint32_t));(void)s;Log(唤醒中...., Notice) \n; }void CloseFifo(int fd) {close(fd); }#ifndef _LOG_H_ #define _LOG_H_#include iostream #include ctime#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#include comm.hpp #include log.hppstring TransToHex(key_t k) {char buffer[32];snprintf(buffer, sizeof buffer, 0x%x, k);return buffer; }int main() {key_t keyftok(PATH_NAME,PROJ_ID);assert(key!-1);Log(create key done, Debug) server key : TransToHex(k) endl;//创建共享内存int shmidshmget(key,SHM_SIZE, IPC_CREAT | IPC_EXCL | 0666);assert(shmid!-1);Log(create shm done, Debug) shmid : shmid endl;sleep(10);// 3. 将指定的共享内存挂接到自己的地址空间char *shmaddr (char *)shmat(shmid, nullptr, 0);Log(attach shm done, Debug) shmid : shmid endl;sleep(10);// 这里就是通信的逻辑了// 将共享内存当成一个大字符串// char buffer[SHM_SIZE];// 结论1 只要是通信双方使用shm一方直接向共享内存中写入数据另一方就可以立马看到对方写入的数据。// 共享内存是所有进程间通信(IPC)速度最快的不需要过多的拷贝不需要将数据给操作系统// 结论2 共享内存缺乏访问控制会带来并发问题 【如果我想一定程度的访问控制呢? 能】int fd OpenFIFO(FIFO_NAME, READ);for(;;){Wait(fd);// 临界区printf(%s\n, shmaddr);if(strcmp(shmaddr, quit) 0) break;// sleep(1);}// 4. 将指定的共享内存从自己的地址空间中取消关联int n shmdt(shmaddr);assert(n ! -1);(void)n;Log(detach 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 : shmid endl;return 0; }#include comm.hppint main() {key_t k ftok(PATH_NAME, PROJ_ID);//创建key值if (k 0){Log(create key failed, Error) client key : k endl;exit(1);}Log(create 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, Error) client key : k endl;sleep(10);char *shmaddr (char *)shmat(shmid, nullptr, 0);//将共享内存关联到进程地址空间if(shmaddr nullptr){Log(attach shm failed, Error) client key : k endl;exit(3);}Log(attach shm success, Error) client key : k endl;sleep(10);int fd OpenFIFO(FIFO_NAME, WRITE);//使用// client将共享内存看做一个char 类型的bufferwhile(true){ssize_t s read(0, shmaddr, SHM_SIZE-1);if(s 0){shmaddr[s-1] 0;Signal(fd);if(strcmp(shmaddr,quit) 0) break;}}CloseFifo(fd)// 去关联int n shmdt(shmaddr);//取消关联assert(n ! -1);Log(detach shm success, Error) client key : k endl;sleep(10);// client 要不要chmctl删除呢不需要return 0; }
http://wiki.neutronadmin.com/news/250218/

相关文章:

  • 制作公司网站价格wordpress 商业网站
  • 汽车配件外贸网站火车票网站开发
  • 南宁建设银行官网招聘网站飞天侠调用wordpress
  • 房屋租赁网站开发需求分析网站建设会计分录
  • 怎么做网站不被发现内蒙网站开发
  • 企业网站模板带后台企业内部管理软件
  • 中国做网站推广哪家好365房产南京网站
  • 大自然的网站设计易网网站
  • 个人网站设计的意义网络营销的方式有几种
  • 网站管理平台扩展插件微信文章导入wordpress
  • 石家庄做外贸的网站推广公司注册代理费
  • wordpress 网站很卡更改wordpress登录地址
  • 烟台网站优化2022年国内重大新闻
  • 企业标准型手机网站网站顶部地图代码怎么做的
  • 网站建设策划公司地址合肥网站优化搜索
  • 各行各业网站建设服务周到做商品网站需要营业执照
  • 营销网站建设网站设计wordpress 重新安装
  • 怎么在另外一台电脑的浏览器打开自己做的网站地址栏输入什么qq上传空间wordpress
  • 素材网站视频网站建设话语
  • 广州制作网站公司电话网站建设和运行费用
  • 帮做动态头像的网站番禺本地网站
  • 网站开发一定找前端么聊城高新区建设局网站
  • 一个空间放2个网站wordpress填写
  • 网站开发逻辑房屋装修效果图制作
  • 长沙seo公司网站优化网站缓存优化怎么做
  • 沈阳个人网站制作做网站的硬件和软件环境
  • 江西省水利水电建设集团招标网站asp个人网站怎么建设
  • 做网站采集禅城技术支持骏域网站建设
  • 台州网站建设推广公司手机网站seo怎么做
  • 如何进入网站管理页面洞泾做网站公司