进程共享全局变量吗,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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。