进程共享全局变量吗,python多线程变量共享

  进程共享全局变量吗,python多线程变量共享

  什么是共享内存?

  百度定义:共享内存是指在多处理器计算机系统中,可以从不同的中央处理器(CPU)访问的大容量内存。因为多个CPU必须高速访问内存,所以需要缓存内存。任何缓存数据更新后,其他处理器也可能访问共享内存,因此必须立即更新。否则,不同的处理器可能使用不同的数据。

  共享内存是Unix中多个进程之间的通信方法。这种方法通常用于程序的多个进程之间的通信。事实上,多个程序也可以通过共享内存传输信息。

  支撑点

  共享内存是最快的IPC格式,允许多个进程访问同一个内存空间。它是为其他通信机制的低效率而设计的。

  但由于共享内存没有互斥的访问机制,所以往往结合信号量等其他通信机制来实现进程间的同步和互斥。

  关于函数

  Ftok:当系统建立IPC通信(消息队列、信号和共享内存)时,必须指定ID值

  头文件

  #包括

  #包括

  复制代码

  功能原型

  key_tFtok(constchar*fname,int id)))))))))))))).

  Fname:使用指定的文件名(现有文件名),通常是当前目录。例如:“.”

  Id:id是一个子序列号。虽然是int类型,但是只用了8位(1-255)。

  在一个典型的UNIX实现中,取出文件的索引节点号,将子节点号追加到前面,得到key _ t的返回值。

  :指定文件的索引节点号是65538,转换为十六进制的0x010002,指定的ID值是38。

  如果转换成十六进制的0x26,那么最后一个key_t的返回值就是0x26010002。

  查询文件索引节点号的方法是ls -i I。

  删除重建的文件时,操作系统将根据当前文件系统的使用情况指定索引节点号。

  所以因为和原来不一样,所以得到的inode号也不一样。

  复制代码

  Shmget:获取共享内存标识符,或者创建一个共享内存对象并返回共享内存标识符

  头文件

  #包括

  #包括

  复制代码功能原型

  intshmget(key_tkey,size_t size,int shmflg)).

  键

  0(IPC_private):创建新的共享内存对象。

  大于0的32位整数:操作由参数shmflg决定。通常,该值必须基于从ftok返回的IPC密钥值。

  大小

  大于0的整数:新创建的共享内存的大小。以字节为单位。

  0:仅获取共享内存时指定0。

  shmflg

  0:获取共享内存标识符,否则函数报错。

  IPC _ creat:如果shmflgipc _ creat为true,那么如果内核中没有键值等于key的共享内存,那么会创建一个新的共享内存;如果存在这样的共享内存,则返回该共享内存的标识符。

  IPC_CREATIPC_EXCL:如果内核中没有key值等于key的共享内存,则新建一个共享内存;如果存在这样的共享内存,将会报告一个错误。

  使用时,必须执行IPC对象(如0600)的permission 操作,以确定信号量集的权限。

  函数返回值

  成功:返回共享内存的标识符。

  错误:-1,错误原因是Error。

  错误代码

  EINVAL:参数大小小于SHMMIN或大于或等于SHMMAX。

  exist:key指向的共享内存已经提前创建,但是已经存在。

  EIDRM:参数key指向的共享内存已被删除。

  ENOSPC:超过了系统可以建立的最大共享内存(SHMALL)。

  e not:参数key指向的共享内存不存在,参数shmflg中没有设置IPC_CREAT位。

  EACCES:不允许。

  ENOMEM:核心内存不足。

  复制代码

  Shmat)共享内存标识符连接到shmid共享内存。成功连接后,共享内存区域对象被映射到调用者的地址空间,这样就可以像访问本地空间一样访问它。

  头文件

  #包括

  #包括

  复制代码功能原型

  void*shmat(intshmid,const void *shmaddr,int shmflg)).

  Hmid:共享内存标识符

  Shmaddr:指定进程内存地址在共享内存中的位置,直接指定NULL,这样内核自己就可以确定合适的地址位置。

  SHF LG:SHM _ rd only:只读模式,其他为读写模式。

  fork之后,子进程继承连接的共享内存地址。

  Exec,这个子进程将自动从连接的共享内存地址中分离出来。

  当该过程结束时,连接的共享内存地址将被自动释放(参见)。

  函数返回值

  成功:额外的共享内存地址

  错误:-1,错误

  原因存储在errno中

  错误代码

  EACCES:没有以指定方式连接共享内存的权限。

  EINVAL:无效的参数shmid或shmaddr

  ENOMEM:核心内存不足。

  复制代码

  Sht:与shmdt函数相反,它用于断开连接点的地址到共享内存的连接,并禁止这个进程访问这个共享内存。

  头文件

  #包括

  #包括

  复制代码功能原型

  int shmdt(const void *shmaddr)

  Shmaddr:连接的共享内存的起始地址。

  这个函数调用并不删除指定的共享内存区域,而只是从当前进程中分离出先前附加了shmat函数的共享内存。

  函数返回值

  成功:0

  错误:-1,错误原因存储在Error中。

  错误代码

  EINVAL:无效的参数shmaddr

  复制代码

  Shmctl:完成共享内存的控制

  头文件

  #包括

  #包括

  复制代码功能原型

  int shmctl(int shmid,int cmd,struct shmid_ds *buf)

  共享内存标识符

  煤矿管理局

  IPC_STAT:获取共享内存的状态,将共享内存的shmid_ds结构复制到buf中。

  IPC_SET:改变共享内存的状态,将buf指向的shmid_ds结构中的uid、gid、mode复制到共享内存的shmid_ds结构中。

  删除这个共享内存。

  共享内存管理结构。详情请参考共享内存内核结构定义一节。

  函数返回值

  成功:0

  错误:-1,错误原因存储在Error中。

  错误代码

  EAC:参数cmd是IPC_STAT,所以你真的没有权限读取这个共享内存。

  参数buf指向一个无效的内存地址。

  EIDRM:标识符为shmid的共享内存已被删除。

  EINVAL:无效的参数cmd或shmid

  EPERM:参数cmd为IPC_SET或IPC_RMID,但没有足够的权限执行它。

  复制代码

  实例代码

  shm_write.c

  #包括

  #包括

  #包括

  #包括

  #包括

  int main(int argc,const char * argv[]) {

  //生成密钥

  key_t key=ftok(。/, 88);

  //创建一个共享内存并返回一个id

  //数字4、2和1表示读取、写入和执行权限

  //用户、用户所属的组以及其他组具有读写权限。

  int shmid=shmget(key,8,IPC _ CREAT 0666);//IPC_CREAT:如果键不存在,则创建条目

  if (shmid==-1) {

  perror(shmget失败);

  //exit(0)表示程序正常退出,exit (1)/exit (-1)表示程序异常退出。

  出口(1);

  }

  //映射共享内存以获取虚拟地址。

  //shmaddr:指定共享内存出现在进程内存地址的什么位置,直接指定NULL让内核自己决定一个合适的地址位置。

  //shmflg: SHM_RDONLY:只读模式,其他为读写模式。

  void *p=shmat(shmid,NULL,0);

  if (p==(void *)-1) {

  perror(shmat失败);

  出口(2);

  }

  //写入共享内存

  int * PP=p;

  * pp=0x123456

  *(PP 1)=0x ffffff;

  //取消映射

  if (shmdt(p)==-1) {

  printf(shmdt失败);

  出口(3);

  }

  Printf(取消映射成功,点击回车销毁共享内存\ n );

  getchar();

  //IPC_RMID:删除这个共享内存。

  if (shmctl(shmid,IPC_RMID,NULL)) {

  perror(shmctl失败);

  出口(4);

  }

  返回0;

  }

  复制代码

  shm_read.c

  #包括

  #包括

  #包括

  #包括

  #包括

  int main() {

  //生成密钥

  key_t key=ftok(。/, 88);

  //获取共享内存并返回id

  //0: 0在仅获取共享内存时指定。

  //shmflg0:获取共享内存标识符。如果不存在,该函数将报告一个错误。

  int shmid=shmget(key,0,0);

  if (shmid==-1) {

  perror(shmget失败);

  出口(1);

  }

  //映射共享内存以获取虚拟地址。

  void *p=shmat(shmid,0,0);

  if (p==(void *)-1) {

  perror(shmat失败);

  出口(2);

  }

  //读取共享内存

  int data1=*(int *)p;

  int data 2=*((int *)p 1);

  Printf(从共享内存中读取,%x和%x\n ,data1,data2

  //取消映射

  if(shmdt(p)==-1) {

  perror(shmdt失败);

  出口(3);

  }

  返回0;

  }

  复制代码

  编译代码

  clang -o shm_write shm_write.c

  clang -o shm_read shm_read.c

  复制代码

  执行代码。/shm _写入。/shm _ red

  复制代码

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: