2 개의 개별 프로세스간에 인 메모리 데이터를 공유 할 수 있습니까?
Twisted를 사용하는 xmlrpc 서버가 있습니다. 서버에는 엄청난 양의 데이터가 메모리에 저장되어 있습니다. 첫 번째 서버의 메모리 내 개체에 액세스 할 수있는 별도의 보조 xmlrpc 서버를 실행할 수 있습니까?
따라서 serverA가 시작되고 객체를 생성합니다. serverB가 시작되고 serverA의 개체에서 읽을 수 있습니다.
* 편집하다 *
공유 할 데이터는 1 백만 개의 튜플 목록입니다.
(주어진 공유 메모리 세그먼트를 사용하고 서로 다른 프로세스간에 호환 가능한 주소를 보장하기 위해) Python 코어 런타임을 깊고 어둡게 다시 작성하지 않으면 일반적인 의미에서 "메모리의 객체를 공유"할 방법이 없습니다. 이 목록은 백만 개의 튜플 주소를 보유하고 각 튜플은 모든 항목의 주소로 구성되며 이러한 각 주소는 필연적으로 프로세스간에 달라지고 힙 전체에 퍼지는 방식으로 pymalloc에 의해 할당됩니다.
Windows를 제외한 거의 모든 시스템에서 부모 프로세스가 해당 개체를 변경하지 않는 한 기본적으로 부모 프로세스 공간의 개체에 대한 읽기 전용 액세스 권한이있는 하위 프로세스를 생성 할 수 있습니다. 그것은 전화로 얻은os.fork()
, 실제로는 현재 프로세스의 모든 메모리 공간을 "스냅 샷"하고 복사 / 스냅 샷에서 다른 동시 프로세스를 시작합니다. 모든 최신 운영 체제에서 이것은 "쓰기시 복사"접근 방식 덕분에 실제로 매우 빠릅니다. 포크 후 두 프로세스에 의해 변경되지 않은 가상 메모리 페이지는 실제로 복사되지 않습니다 (대신 동일한 페이지에 대한 액세스가 공유 됨). ; 어느 한 프로세스가 이전에 공유 된 페이지의 비트를 수정하자마자 해당 페이지가 복사되고 페이지 테이블이 수정되므로 수정 프로세스는 이제 자체 복사본을 가지지 만 다른 프로세스는 여전히 원본을 볼 수 있습니다.
이 극도로 제한된 형태의 공유는 어떤 경우에는 여전히 생명의 은인이 될 수 있습니다 (극히 제한적 임에도 불구하고 : 예를 들어 공유 객체에 대한 참조를 추가하는 것은 참조 횟수로 인해 해당 객체를 "변경"하는 것으로 간주되어 페이지를 강제 실행합니다. copy!) ... 물론 Windows에서는 사용할 수없는 경우를 제외하고. 이 단일 예외 (사용 사례를 다루지 않을 것 같음)를 제외하고는 다른 객체에 대한 참조 / 포인터를 포함하는 객체 그래프를 공유하는 것은 기본적으로 불가능하며 현대 언어 (Python 포함)에서 관심있는 거의 모든 객체 세트 이 분류에 속합니다.
극단적 인 (그러나 충분히 단순한) 경우에는 그러한 객체 그래프의 기본 메모리 표현을 포기함으로써 공유를 얻을 수 있습니다. 예를 들어, 각각 16 개의 부동 소수점이있는 백만 개의 튜플 목록은 실제로 128MB의 공유 메모리 단일 블록으로 표현 될 수 있습니다. 모든 16M 부동 소수점은 배정 밀도 IEEE 표현으로 끝이 나옵니다. 정상적 방식으로 문제를 처리하고있는 "처럼 보이게"하려면 (물론 그다지 작지 않은 심도 프로세스 간 동기화 문제를 처리해야합니다. 일어날 것이 확실합니다 ;-). 거기에서 더 털이 많고 복잡해집니다.
동시성에 대한 현대적인 접근 방식은 비공유 방식을 선호하는 공유 방식을 점점 더 무시하고 있습니다. 여기서 작업은 메시지 전달을 통해 통신합니다 (스레딩 및 공유 주소 공간을 사용하는 멀티 코어 시스템에서도 동기화 문제 및 성능이 HW에 영향을 미침). 많은 메모리 영역이 한 번에 여러 코어에 의해 능동적으로 수정되어 사람들을 밀어 내고있을 때 캐싱, 파이프 라인 중단 등의 측면에서 발생합니다.
예를 들어, Python의 표준 라이브러리에있는 다중 처리 모듈은 메모리 공유가 아니라 (확실히 R / W 방식이 아닙니다!-) 객체를 앞뒤로 피클 링하고 전송하는 데 주로 의존합니다.
나는 이것이 OP에 대한 반가운 소식이 아니라는 것을 알고 있지만 여러 프로세서를 작동시켜야 할 경우 메시지 전달을 통해 액세스하고 수정할 수있는 위치에 공유해야하는 모든 항목을 상주하는 관점에서 생각하는 것이 좋습니다. -데이터베이스, Memcache 클러스터, 데이터를 메모리에 보관하고 요청시 송수신하는 전용 프로세스 및 기타 메시지 전달 중심 아키텍처.
mmap.mmap(0, 65536, 'GlobalSharedMemory')
동일한 메모리를 공유하려는 모든 프로세스에 대해 태그 ( "GlobalSharedMemory")가 동일해야한다고 생각합니다.
http://docs.python.org/library/mmap.html
Python에서 저수준 공유 메모리 조작에 사용할 수있는 타사 라이브러리 가 두 개 있습니다.
둘 다 pip를 통해 사용할 수 있습니다.
[1] 다른 패키지 shm을 사용할 수 있지만 더 이상 사용되지 않습니다 . 라이브러리 비교는 이 페이지 를 참조하십시오 .
C-Python 통신을위한 예제 코드 c / o Martin O'Hanlon :
shmwriter.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main(int argc, const char **argv)
{
int shmid;
// give your shared memory an id, anything will do
key_t key = 123456;
char *shared_memory;
// Setup shared memory, 11 is the size
if ((shmid = shmget(key, 11, IPC_CREAT | 0666)) < 0)
{
printf("Error getting shared memory id");
exit(1);
}
// Attached shared memory
if ((shared_memory = shmat(shmid, NULL, 0)) == (char *) -1)
{
printf("Error attaching shared memory id");
exit(1);
}
// copy "hello world" to shared memory
memcpy(shared_memory, "Hello World", sizeof("Hello World"));
// sleep so there is enough time to run the reader!
sleep(10);
// Detach and remove shared memory
shmdt(shmid);
shmctl(shmid, IPC_RMID, NULL);
}
shmreader.py
import sysv_ipc
# Create shared memory object
memory = sysv_ipc.SharedMemory(123456)
# Read value from shared memory
memory_value = memory.read()
# Find the 'end' of the string and strip
i = memory_value.find('\0')
if i != -1:
memory_value = memory_value[:i]
print memory_value
특정 목적을 위해 공유 메모리 배열을 만들고 조작하는 C 라이브러리를 작성한 다음 ctypes를 사용하여 Python에서 액세스 할 수 있습니다.
또는 / dev / shm (tmpfs)의 파일 시스템에 저장합니다. 매우 적은 성능 오버 헤드로 많은 개발 노력을 절약 할 수 있습니다. tmpfs 파일 시스템의 읽기 / 쓰기는 memcpy에 불과합니다.
Python Multiprocessing 모듈을 사용할 수 있습니다.
http://docs.python.org/library/multiprocessing.html#sharing-state-between-processes
사실 간단합니다. 공유 메모리를 사용할 수 있습니다. 이 예제는 C ++로 튜플 (python) 목록을 만들고 튜플 목록을 사용할 수있는 python 프로세스와 공유합니다. 두 Python 프로세스간에 사용하려면 ACCESS_WRITE
발신자 프로세스에서와 같이 액세스 하고 write
메서드를 호출하면 됩니다.
C ++ (발신자 프로세스) :
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <iostream>
#include <string>
#define BUF_SIZE 256
TCHAR szName[]=TEXT("Global\\MyFileMappingObject");
TCHAR szMsg[]=TEXT("[(1, 2, 3), ('a', 'b', 'c', 'd', 'e'), (True, False), 'qwerty']");
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE hMapFile;
LPCTSTR pBuf;
hMapFile = CreateFileMapping(
INVALID_HANDLE_VALUE, // use paging file
NULL, // default security
PAGE_READWRITE, // read/write access
0, // maximum object size (high-order DWORD)
BUF_SIZE, // maximum object size (low-order DWORD)
szName); // name of mapping object
if (hMapFile == NULL)
{
_tprintf(TEXT("Could not create file mapping object (%d).\n"),
GetLastError());
return 1;
}
pBuf = (LPTSTR) MapViewOfFile(hMapFile, // handle to map object
FILE_MAP_ALL_ACCESS, // read/write permission
0,
0,
BUF_SIZE);
if (pBuf == NULL)
{
_tprintf(TEXT("Could not map view of file (%d).\n"),
GetLastError());
CloseHandle(hMapFile);
return 1;
}
CopyMemory((PVOID)pBuf, szMsg, (_tcslen(szMsg) * sizeof(TCHAR)));
_getch();
UnmapViewOfFile(pBuf);
CloseHandle(hMapFile);
return 0;
}
Python (수신자 프로세스) :
import mmap
shmem = mmap.mmap(0,256,"Global\\MyFileMappingObject",mmap.ACCESS_READ)
msg_bytes = shmem.read()
msg_utf16 = msg_bytes.decode("utf-16")
code = msg_utf16.rstrip('\0')
yourTuple = eval(code)
공유 데이터를 Memcache 서버에 저장하지 않는 이유는 무엇입니까? 그러면 두 서버 모두 매우 쉽게 액세스 할 수 있습니다.
데이터가 단순히 튜플이고 이러한 데이터에 액세스하려는 경우
- (nrows x tuplewidth)
np.ndarray
s 또는 - n 1 일
np.ndarrays
그런 다음 memmap에 numpy의 래퍼를 사용하는 것이 좋습니다 .
내 이해는 다음과 같습니다.
- numpy 배열을 원시 배열 내용을 보유하는 평면 memmap 파일로 저장합니다.
- each process points an ndarray to the memmap file as its backing data. The documentation link shows how.
This works great for read-only data. If you want read-write, you'll need to uses the multiprocess locks to protect access.
Because memmap uses paging to load the data its a blazingly fast way to access large datasets from disk. In fact, I don't think modern OSs have any faster to loaded data from disk into memory than this -- no serialization is involved.
Why not just use a database for the shared data? You have a multitude of lightweight options where you don't need to worry about the concurrency issues: sqlite, any of the nosql/key-value breed of databases, etc.
ReferenceURL : https://stackoverflow.com/questions/1268252/possible-to-share-in-memory-data-between-2-separate-processes
'IT TIP' 카테고리의 다른 글
bash 스크립트에서 다른 사용자의 $ HOME 디렉토리를 얻는 방법은 무엇입니까? (0) | 2020.12.28 |
---|---|
py.test를 실행하는 동안 ImportMismatchError 오류가 발생합니다. (0) | 2020.12.28 |
UIImagePickerController가 화면을 채우지 않습니다. (0) | 2020.12.28 |
C #은 foreach의 if 문을 기반으로 목록의 다음 항목으로 이동합니다. (0) | 2020.12.28 |
BitmapImage를 Bitmap으로 또는 그 반대로 변환 (0) | 2020.12.28 |