共享内存

python多进程共享内存的读写访问控制

怎甘沉沦 提交于 2019-12-21 19:58:50
问题背景 基于SharedArray库,可以实现python多进程共享内存机制。问题在于,当内存初始化完成之后,我们希望这片内存的属性是只读的,而不希望看到意外的修改发生。 解决方案 解决方案是修改SharedArray库,库函数API attach成员提供的参数原先只有一个,即共享内存的文件名。通过修改attach的输入参数,可以允许用户将映射的内存指定为只读属性。这里面最关键的是mmap函数,attach函数内部调用mmap函数,原先的实现是将读写属性固定为允许读写。我们只需要略加修改,允许根据用户指定的参数来配置mmap,就可以达到内存区只读的目的。 测试结果 实测的结果是,将共享内存设置为read only之后,程序对于该内存的写操作会触发segment fault。 来源: CSDN 作者: hicode666 链接: https://blog.csdn.net/hicode666/article/details/103646590

JMM和底层实现原理

旧巷老猫 提交于 2019-12-21 10:32:07
一、 并发编程领域的关键问题 1.线程之间的通信和同步 1.1 线程之间的通信 线程的通信是指线程之间以何种机制来交换信息。在编程中,线程之间的通信机制有两种, 共享内存 和 消息传递 。 1.1.1 共享内存 在共享内存的并发模型里,线程之间共享程序的公共状态, 线程之间通过写-读内存中的公共状态来隐式进行通信 ,典型的共享内存通信方式就是通过 共享对象进行通信 。 1.1.2 消息传递 在消息传递的并发模型里,线程之间没有公共状态, 线程之间必须通过明确的发送消息来显式进行通信 ,在java中典型的消息传递方式就是wait()和notify()。 1.2 线程之间的同步 同步是指程序用于控制不同线程之间操作发生相对顺序的机制。 在共享内存并发模型里,同步是显式进行的 。程序员必须显式指定某个方法或某段代码需要在线程之间互斥执行。 在消息传递的并发模型里,由于消息的发送必须在消息的接收之前,因此同步是隐式进行的 。 解释:同步就是协同步调,按预定的先后次序进行运行。如:你说完,我再说。线程同步的真实意思和字面意思恰好相反。线程同步的真实意思,其实是“排队”:几个线程之间要排队,一个一个对共享资源进行操作,而不是同时进行操作。 结论:Java的并发采用的是共享内存模型 二、 Java 内存模型( JMM ) 1. 定义和解释 即 Java Memory Model ,简称 JMM;

[linux] 进程间通讯的几种方式

蓝咒 提交于 2019-12-21 02:51:05
linux进程间通信(IPC)有几种方式,下面将将简单的简述一下:   一。管道(pipe)   管道是Linux支持的最初IPC方式,管道可分为无名管道,有名管道等。   (一)无名管道,它具有几个特点:   1) 管道是半双工的,只能支持数据的单向流动;两进程间需要通信时需要建立起两个管道;   2) 无名管道使用pipe()函数创建,只能用于父子进程或者兄弟进程之间;   3) 管道对于通信的两端进程而言,实质上是一种独立的文件,只存在于内存中;   4) 数据的读写操作:一个进程向管道中写数据,所写的数据添加在管道缓冲区的尾部;另一个进程在管道中缓冲区的头部读数据。   (二)有名管道   有名管道也是半双工的,不过它允许没有亲缘关系的进程间进行通信。具体点说就是,有名管道提供了一个路径名与之进行关联,以FIFO(先进先出)的形式存在于文件系统中。这样即使是不相干的进程也可以通过FIFO相互通信,只要他们能访问已经提供的路径。   值得注意的是,只有在管道有读端时,往管道中写数据才有意义。否则,向管道写数据的进程会接收到内核发出来的SIGPIPE信号;应用程序可以自定义该信号处理函数,或者直接忽略该信号。   二。信号量(semophore)   信号量是一种计数器,可以控制进程间多个线程或者多个进程对资源的同步访问,它常实现为一种锁机制。实质上,信号量是一个被保护的变量

Apache重启失败name-based shared memory failure

若如初见. 提交于 2019-12-18 21:53:49
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 新编译apache的module,在make install的时候没有停止apache,可能会导致apache重启失败。 典型错误信息:File exists: unable to create scoreboard "/usr/local/apache/logs/httpd.scoreboard" (name-based shared memory failure) 如果将错误定位在httpd.scoreboard文件上,删除或者改名往往并不能解决问题。其实错误的重点在于:shared memory。 真正的原因是:因为替换了正在工作的so文件,造成关闭时无法正常释放内部共享内存,再次启动时检查到错误导致apache无法启动。 解决办法: ipcs -m -p 检查占用共享内存的进程,返回数据格式: shmid owner cpid lpid 一般cpid和lpid是一致的,在ps中查找,如果cpid和lpid都不存在,那么说明这块共享内存是没有被释放的。 ipcrm -m 用上面查出的pid的shmid,通过上面的命令释放共享内存 然后再检查一遍是否释放了:ipcs -m -p 再次启动apache就OK了。 来源: oschina 链接: https://my.oschina.net/u/2407990

使用Share Memory时的shmget失败与ftok的关系。

此生再无相见时 提交于 2019-12-18 03:40:56
对于长期运行的系统,产生的日志是大量的,即使每2秒一条,一天也有4W多条。假如我们只需要在想观察的时候动态地看到当前记录或计数,那么可以将日志的信息写到一个共享内存区,然后写一个LogReader,去访问这个共享内存区即可。 要使用共享内存,应该有如下步骤: 1.开辟一块共享内存 shmget() 2.允许本进程使用共某块共享内存 shmat() 3.写入/读出 需要删除这块内存的时候,步骤为 4.禁止本进程使用这块共享内存 shmdt() 5.删除这块共享内存 shmctl()或者命令行下ipcrm 过程会用到以下的这些函数: int shmget( key_t shmkey , int shmsiz , int flag ); 创建一个新的共享内存区或打开一存在的共享内存区 void *shmat( int shmid , char *shmaddr , int shmflag ); 返回共享内存区在调用进程内的起始地址。 shmaddr最好设置为NULL,这样系统会替我们选择地址,可移植性更强;否则会根据shmflag时候指定了SHM_RND,将共享内存区附接到shmaddr参数指定的地址。 今天调试的时候发现了以下的这些问题:两个需要通信的进程使用一个同样的字符串调用ftok生成key,并对该key调用shmget,其中有一个不能访问到共享内存区。查阅了UNP2才明白了。

深浅copy

守給你的承諾、 提交于 2019-12-17 08:14:29
copy, deepcopy 的区别? 针对不可变类型 赋值,浅copy,深copy都是相同的,都是指针的引用,没有开辟新的内存,完全共享数据 针对可变类型 赋值是共享内存 数据只有一层时,浅copy,深copy都是完全开辟不同内存空间,数据独立 当数据有父子层时,也就是数据嵌套 浅copy,父层是不共享内存,子层及更深层数据共享内存 深copy,父子层完全独立 来源: https://www.cnblogs.com/lisen321/p/11958607.html

Linux系统编程(5)——文件与IO之mmap函数

孤街浪徒 提交于 2019-12-17 02:47:16
mmap系统调用它本身提供了不同于一般对普通文件的访问方式,进程可以像读写内存一样对普通文件的操作。而Posix或系统V的共享内存IPC则纯粹用于共享目的,mmap()实现共享内存也是其主要应用之一。mmap系统调用使得进程之间通过映射同一个普通文件实现共享内存。普通文件被映射到进程地址空间后,进程可以像访问普通内存一样对文件进行访问,不必再调用read(),write()等操作。 我们的程序中大量运用了mmap,用到的正是mmap的这种“像访问普通内存一样对文件进行访问”的功能。实践证明,当要对一个文件频繁的进行访问,并且指针来回移动时,调用mmap比用常规的方法快很多。简单说就是把一个文件的内容在内存里面做一个映像,内存比磁盘快些。基本上它是把一个文件对应到virtual memory 中的一段,并传回一个指针。以后对这段内存做存取时,其实就是对那个档做存取。它就是一种快速文件I/O,而且使用上和存取内存一样方便,只不过会占掉你的 virutal memory。 mmap这个系统调用可以直接对底层的操作,映射硬件地址,实现用户层驱动。 #include <sys/mman.h> void*mmap(void *addr, size_t len, int prot, int flag, int filedes, off_t off); intmunmap(void *addr,

System V IPC

北城以北 提交于 2019-12-16 18:21:35
1、概述    System V IPC共有三种类型:System V消息队列、System V 信号量、System V 共享内存区。 System V IPC操作函数如下: 2、key_t键和ftok函数   三种类型的IPC使用key_t值作为他们的名字,头文件<sys/types.h>把key_t定义为一个整数,通常是一个至少32位的整数,由ftok函数赋予的。函数ftok把一个已存的路径和一个整数标识符转换成一个key_t值,称为IPC键。函数原型如下: #include <sys/types.h>#include <sys/ipc.h> key_t ftok(const char *pathname, int proj_id); //成功返回IPC键,出错返回-1 写个程序看看ftok是如何组合IPC键,程序如下: 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 #include <sys/types.h> 5 #include <sys/ipc.h> 6 #include <sys/stat.h> 7 #include <errno.h> 8 9 typedef unsigned long u_long; 10 11 int main(int argc,char *argv[])

Oracle-安装

有些话、适合烂在心里 提交于 2019-12-16 13:51:18
一、关闭防火墙   (1)[root@oracle ~]# vim /etc/selinux/config     [root@oracle ~]# setenforce 0     [root@oracle ~]# getenforce   (2)[root@oracle ~]# systemctl stop firewalld.service      [root@oracle ~]# systemctl status firewalld.service 二、创建用户和组及安装目录,安装依赖包 (1)创建用户和组   [root@oracle ~]# groupadd oinstall   [root@oracle ~]# groupadd dba   [root@oracle ~]# useradd -g oinstall -G dba -m oracle   [root@oracle ~]# passwd oracle (2)创建安装目录,上传oracle压缩包,并解压,给新建的目录设置权限   [root@oracle ~]# mkdir -p /ora/oracle   [root@oracle database]# chown -R oracle:oinstall /ora/   [root@oracle database]# chmod -R 755 /ora/  

记一次腾讯面试:进程之间究竟有哪些通信方式?如何通信? ---- 告别死记硬背

試著忘記壹切 提交于 2019-12-16 10:54:33
有一次面试的时候,被问到进程之间有哪些通信方式,不过由于之前没深入思考且整理过,说的并不好。想必大家也都知道进程有哪些通信方式,可是我猜很多人都是靠着”背“来记忆的,所以今天的这篇文章,讲给大家详细着讲解他们是如何通信的,让大家尽量能够理解他们之间的区别、优缺点等,这样的话,以后面试官让你举例子,你也能够顺手拈来。 1、管道 我们来看一条 Linux 的语句 netstat -tulnp | grep 8080 学过 Liux 命名的估计都懂这条语句的含义,其中”|“是管道的意思,它的作用就是把前一条命令的输出作为后一条命令的输入。在这里就是把 netstat -tulnp 的输出结果作为 grep 8080 这条命令的输入。如果两个进程要进行通信的话,就可以用这种管道来进行通信了,并且我们可以知道这条竖线是没有名字的,所以我们把这种通信方式称之为匿名管道。 并且这种通信方式是单向的,只能把第一个命令的输出作为第二个命令的输入,如果进程之间想要互相通信的话,那么需要创建两个管道。 居然有匿名管道,那也意味着有命名管道,下面我们来创建一个命名管道。 mkfifo test 这条命令创建了一个名字为 test 的命名管道。 接下来我们用一个进程向这个管道里面写数据,然后有另外一个进程把里面的数据读出来。 echo "this is a pipe" > test // 写数据 1