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

网站建设更新维护工作网络推广平台公司

网站建设更新维护工作,网络推广平台公司,哪里做网站最好网站,做网站买域名怎么弄"My poor lost soul"上章花了不少的篇幅讲了讲基于管道((匿名、命名))技术实现的进程间通信。进程为什么需要通信?目的是为了完成进程间的"协同",提高处理数据的能力、优化业务逻辑的实现等等,在linux中我们已经谈过了一个通信的大类…

"My poor lost soul"

上章花了不少的篇幅讲了讲基于管道((匿名、命名))技术实现的进程间通信。进程为什么需要通信?目的是为了完成进程间的"协同",提高处理数据的能力、优化业务逻辑的实现等等,在linux中我们已经谈过了一个通信的大类——管道。根据System V标准的基础上提出了,另一套进程通信的标准。

-----前言


一、System V简介

System V,曾经也被称为AT&TSystem V,是Unix操作系统众多版本中的一支。
System V的第一个版本,发布于1983年。它引进了一些特性,例如vi编辑器和curses库。其中也包括了对DEC VAX机器的支持。同时也支持使用消息进行进程间通信,信号量和共享内存。 取自这里

为什么这么"隆重"地介绍System V呢?因为这是一套通信标准。当在后面学了共享内存的多个API后,你会发现消息队列、信号量的接口函数极为相似。

二、共享内存

共享内存是进程间通信中最简单的方式之一。共享内存允许两个或更多进程访问同一块内存,就如同 malloc() 函数向不同进程返回了指向同一个物理内存区域的指针。当一个进程改变了这块地址中的内容的时候,其它进程都会察觉到这个更改。 取自这里

文字描述显然很恼人,我们直接上图。

通信的本质,就是让不同能够看到同一份资源。

由此,我们对共享内存的理解是:其本质就是开辟在物理内存里的一块内存块,用来进行IPC通信的。
让需要通信的进程能够看到这块内存块,并在上面进行通信行为。

三、实现共享内存

(1)创建共享内存块

#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg);

shmget() returns the identifier of the System V shared memory segment associated with the value of the argument key. A new shared memory segment, with size equal to the value of size rounded up to a multiple of PAGE_SIZE, is created if key has the value IPC_PRIVATE or key isn't IPC_PRIVATE, no shared memory segment corresponding to key exists, and IPC_CREAT is specified in shmflg.
这里也就简单说说shmget的参数。

key:这个参数至关重要。它是连接共享内存,找到共享内存块的关键。也就是说,一个进程只要拿到了在这个key值,就可以访问这一块内存块。
size:申请共享内存块的大小。这个size会按照PAGE_SIZE大小(向上对齐)。
shmflg:我们常用的参数就是 IPC_CREATE \ IPC_EXCL:
IPC_CREATE:如果不存在就创建、如果存在就获取
IPC_EXCL:不能单独使用。IPC_CREATE | IPC_EXCL 如果不存在就创建,存在就返回错误(保证给用户的共享内存块一定是新创建的)。

如果创建成功,shmget会返回一个有效标记内存块的标识符

那么怎么形成key这个唯一标识的关键字呢?库里给我们提供了一个函数,可以让生成的key是一个唯一标识的数字key_t类型。

#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);

convert a pathname and a project identifier to a System V IPC key:用pathname + proj_id转换为key

并且这个pathname不是随便乱取的。而是一个"现有"、"可访问"的文件。

如何让两个进程看到一块共享内存?只需要知道key就行了。key是怎么生成的?ftok(pathname,proj_id)。这两个参数一样,不久可以生成相同的key了嘛?

如何理解key?

在操作系统中,一定会存在多个key_t类型的 有效标识符。那么这么多标识符一定会被操作系统管理。管理的本质:先描述、再组织。

我们举个例子:

我们可以看到,OS会为共享内存块维护一份结构体struct shimid_ds 用来管理共享内存块。

共享内存的生命周期随OS:

我们在学习管道通信时,一旦进程有一方结束,那么双方的通信管道也会随之关闭。为什么现如今,进程结束了,它们申请的共享内存块仍然存在呢??

管道的生命周期随进程,共享内存的生命周期随OS。

为此,我们不得不手动去关闭掉,我们编写的进程所打开的共享内存块。

ipcrm -m + shmid

(2)挂接与去关联

我们现如今拿到了共享内存块的标识符shmid,那么如何通过这个shmid找到共享内存的位置呢?

#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);

shmat() attaches the System V shared memory segment identified by shmid to the address space of the calling process. The attaching address is specified by shmaddr with one of the following criteria.
通过这个函数可以通过shmid 与 共享内存块挂接,并返回该共享内存块的地址。

参数: shmaddr 、shmflag
If shmaddr is NULL, the system chooses a suitable (unused) address at which to attach the segment.
这里我们通常设置为 nullptr,那么OS就会为我们选择一个适合的挂接到了这个内存块的地址。
shmflag通常为设置为0.

返回参数:
On success shmat() returns the address of the attached shared memory segment; on error (void *) -1 is returned, and errno is set to indicate the cause of the error.
如果成功,shmat()返回挂接这个共享内存块的地址,返回-1是error的
void *attachShm(int shmid)
{void *mem = shmat(shmid, nullptr, 0);if ((long long)mem == -1) // Linux下 是64位系统 一个指针大小为8字节{std::cerr << "attachShm: " << mem << std::endl;exit(3);}return mem;
}

#include <sys/types.h>
#include <sys/shm.h>
int shmdt(const void *shmaddr);

shmdt() detaches the shared memory segment located at the address specified by shmaddr from the address space of the calling process. The to-be-detached segment must be currently attached with shmaddr equal to the value returned by the attaching shmat() call.
shmdt()会将传入的共享内存块地址去挂接(关联)。调用shmdt(),必须传入通过shmat()获取的地址。

On success shmdt() returns 0; on error -1 is returned, and errno is set to indicate the cause of the error.
0为去关联成功,-1位失败。
void detachShm(void* start)
{int ret = shmdt(start);if(ret == -1){std::cerr << "attachShm: " << ret << std::endl;exit(4);}
}

(3)释放共享内存块

共享内存块的生命周期随OS,我们每申请共享内存空间,都得"ipcrm -m + shmid"释放内存空间,当我们不再使用时,这未免太过麻烦了。

#include <sys/ipc.h>
#include <sys/shm.h>

int shmctl(int shmid, int cmd, struct shmid_ds *buf);
shmctl() performs the control operation specified by cmd on the System V shared memory segment whose identifier is given in shmid.
shmctl()通过cmd传入的命令操作,对shmid表示的共享内存块进行处理。

要在进程结束时,关闭共享内存,我们需要传入的参数是:
IPC_RMID Mark the segment to be destroyed.
void delShm(int shmid)
{if (shmctl(shmid, IPC_RMID, nullptr) == -1){std::cerr << "delShm: " << shmid << std::endl;exit(5);}
}

当然,shmctl不仅仅可以归还共享内存,当cmd传入的参数是IPC_STAT时,我们可以获取由shmid填充的结构体内容。

像这样:

int main()
{int shmid = shmget(key);struct shmid_ds ds;shmctl(shmid,IPC_STAT,&ds);ds.shm_perm.__key;ds.shm_atime;//..return 0;
}

(4)测试

有了上面对函数的理解和实现,我们可以进行一定的通信了。

我们想让Sever读取client发送的内容: "Hello Server! pid + 发送次数"。

Client:

int main()
{// 1.申请keykey_t key = getKey(PATH_NAME, PROJ_ID);std::cout << "Client key: " << key << std::endl;// 2.申请内存块int shmid = getShm(key);std::cout << "Client shmid: " << shmid << std::endl;// 3.挂接void *start = attachShm(shmid);printf("attach success, address start: %p\n", start);// 真正的通信区域const char* msg = "Hello Server!";int cnt = 0;while (true){   snprintf((char*)start,MAX_PAGE,"%s[pid:%d]编号信息:[%d]\n",msg,getpid(),cnt++);sleep(1);}// 4.去关联detachShm(start);return 0;
}

Server:

int main()
{// 1.申请keykey_t key = getKey(PATH_NAME, PROJ_ID);std::cout << "Server key: " << key << std::endl;// 2.申请内存块int shmid = createShm(key);std::cout << "Server shmid: " << shmid << std::endl;// 3.挂接void *start = attachShm(shmid);printf("attach success, address start: %p\n", start);// 真正的通信区域while (true){printf("client say : %s\n", start);sleep(1);}// 4.去关联detachShm(start);printf("detach success");// 5.关闭共享内存delShm(shmid);return 0;
}

我们来看看效果吧~

这是怎么回事??噢,原来是权限问题。

我们在创建共享内存的时候,需要附上权限大小。

这样就完成了双方进程间的通信。


四、共享内存 vs 管道

但是,管道自带同步与互斥!如果写端不写入,读端会成阻塞状态,直到写端写入,此时有数据可读。但是共享内存不一样,它没有同步与互斥操作,即便写端没有写入数据,读端照样会向内存块中读取。

总结:

①共享内存是一块存在物理内存的,由操作系统管理的内存块。它属于IPC通信方式的一种,在所有的通信方式中速度是最快的。

②共享内存的创建:1.申请(shmget) 2.挂接(shmat) 3.去关联(shmdt) 4.关闭空间(shmctl).

③管道自带同步与互斥,共享内存不支持。

本篇也就告一段落了,感谢你的阅读。

祝你好运~向阳而生。

http://www.hengruixuexiao.com/news/14104.html

相关文章:

  • 传奇手游三端互通新开服网站百度刷排名百度快速排名
  • 销售管理软件排名海外广告优化师
  • 做网站的品牌公司有哪些seo学徒招聘
  • 电子商务的网站建设设计书百度排行榜风云榜
  • 有创意的婚纱网站模板下载快速优化系统
  • 做影视网站怎么赚钱爱站网关键词查询工具
  • 南阳企业网站推广帮人推广的平台
  • 婚姻网站建设注意事项seo网站关键词优化价格
  • 西安网站建设报价seo推广服务哪家好
  • 建设部网站施工合同范本爱站权重查询
  • 湖北省建设厅政务公开网站seo优化师培训
  • 门户网站建设技术要求广告推广营销网站
  • 上海网站建设电影联seo 重庆
  • 外贸网站建设公司排名唐山网站建设方案优化
  • 苏州做网站优化哪家好seo接单平台
  • 创建个人网站名字苹果cms永久免费建站程序
  • 天长网站设计网店推广营销方案
  • 小程序开发公司价格表网站关键词优化培训
  • 程序员做交友网站seo全国最好的公司
  • 分析seo做的不好的网站软件开发一般需要多少钱
  • 南城网站建设价格在哪里可以找到网站
  • 做网站开发的女生多吗网络营销10大平台
  • 怎样做网站让百度能找到百度收录情况查询
  • wordpress 渗透框架整站优化seo平台
  • 做公司+网站建设价格低网站排名优化首页
  • 做网站必须要虚拟主机吗网坛最新排名
  • 赤风设计安卓优化大师旧版本下载
  • 衡水做网站电话关键词seo深圳
  • 做买衣服的网站有哪些nba在线直播免费观看直播
  • 一流的商城网站建设制作网页的教程