我有一个看起来像这样的结构:
typedef struct shared_data_t
{
char *key;
char *message;
}shared_data;
Run Code Online (Sandbox Code Playgroud)
我需要与另一个不相关的进程共享这个结构。我使用 POSIX 共享内存和 shm_open()/mmap() 来实现此目的。然而,我的目标进程没有获取共享数据,并且它因 SIGSEGV 而终止,这是显而易见的。如果有人在这方面帮助我,特别是在具有共享内存的两个进程之间共享指针(使用 shm_open 和 mmap)时会发生什么,那就太好了。
对于这样的结构,
typedef struct shared_data_t
{
char key[8];
char message[32];
}shared_data;
Run Code Online (Sandbox Code Playgroud)
一切正常!
是否可以获取 Linux 中特定文件描述符上的内存映射总量?为了清楚起见,我制作了一个如何打开/创建内存映射的小示例代码:
int fileDescriptor = open(mapname, O_RDWR | O_CREAT | O_EXCL, 0666);
if(fileDescriptor < 0)
return false;
//Map Semaphore
memorymap = mmap(NULL, sizeof(mapObject), PROT_READ | PROT_WRITE, MAP_SHARED, fileDescriptor, 0);
close(fileDescriptor);
Run Code Online (Sandbox Code Playgroud)
内存映射由多个进程使用。我可以访问将使用此内存映射的其他进程的代码库。如何以 100% 正确的方式获取 fileDescriptor 上有多少个映射?
我想使用 POSIX 共享内存,我的问题是关于调用msync()和munmap()之后的使用情况mmap(MAP_SHARED)。
msync()?msync()?msync()?我的印象msync()是仅适用于将更改应用于底层文件而不是共享内存。
当我上学期第一次做这个项目时,代码运行得很好。现在,当写入要在进程之间共享的映射内存时,我收到总线错误,并且我不确定为什么它不再工作。
Account_Info *mapData()
{
int fd;
//open/create file with read and write permission and check return value
if ((fd = open("accounts", O_RDWR|O_CREAT, 0644)) == -1)
{
perror("Unable to open account list file.");
exit(0);
}
//map data to be shared with different processes
Account_Info *accounts = mmap((void*)0, (size_t) 100*(sizeof(Account_Info)), PROT_WRITE,
MAP_SHARED, fd, 0);
int count= 0;
//loop to initialize values of Account_Info struct
while (count != 20)
{
//bus error occurs here
accounts[count].CurrBalance= 0;
accounts[count].flag = 0;
int i = 0; …Run Code Online (Sandbox Code Playgroud) 当我使用 --static 选项构建程序并调用 shm_open() 函数时,出现分段错误。没有 -static 选项,一切都像魅力一样。
有人知道为什么吗?
下面我引用了一个大项目的调试信息和部分截断的源代码。
您可以评论/取消评论
#STATIC = -static
Run Code Online (Sandbox Code Playgroud)
Makefile 中的字符串来重现该错误。
$ gdb --args ./debug/示例sample017
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Reading symbols from ./debug/example...done.
(gdb) run
Starting program: ./example sample017
Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) backtrace
#0 0x0000000000000000 in ?? ()
#1 0x000000000049a2e3 in __shm_directory (len=0x7fffffffdca8) at ../sysdeps/unix/sysv/linux/shm-directory.c:124
#2 0x0000000000499ff3 in shm_open ()
#3 0x0000000000499d55 in read_shm (memory=0x6d1be0, share_name=0x6d1d20 "sample017") at main.c:51
#4 0x0000000000499efe in read_memory (memory=0x6d1be0, argc=0x7fffffffde0c, argv=0x7fffffffdf68) at …Run Code Online (Sandbox Code Playgroud) 当我运行 docker 映像并ipc=host调用shmget在容器中分配共享内存时,我可以运行ipcs -m以在主机上显示此共享内存信息。
如果我使用默认的ipc模式运行docker镜像,我可以运行ipcs -m以显示docker中的共享内存,但我无法使用相同的方法在主机上显示它。
有没有办法显示host\xef\xbc\x8c上docker容器分配的所有共享内存信息,即使ipc模式不是host\xef\xbc\x9f
\n假设我有两个进程,它们都使用shm_open和共享一个内存块,mmap并且存在一个共享同步原语 - 假设是一个信号量 - 确保对内存的独占访问。即没有竞争条件。
我的理解是,从返回的指针mmap仍必须标记为 volatile 以防止缓存读取。
现在,如何将例如 a 写入std::uint64_t内存中的任何对齐位置?
当然,我会简单地使用std::memcpy但它不适用于指向易失性内存的指针。
// Pointer to the shared memory, assume it is aligned correctly.
volatile unsigned char* ptr;
// Value to store, initialize "randomly" to prevent compiler
// optimization, for testing purposes.
std::uint64_t value = *reinterpret_cast<volatile std::uint64_t*>(nullptr);
// Store byte-by-byte
unsigned char* src = reinterpret_cast<unsigned char*>(&value);
for(std::size_t i=0;i<sizeof(value);++i)
ptr[i]=src[i];
Run Code Online (Sandbox Code Playgroud)
神箭。
我坚信这个解决方案是正确的,但即使使用-O3,也有 8 个 1 字节传输。这真的不是最优的。
因为我知道在我锁定内存时没有人会更改内存,所以也许 …
我正在尝试将大型对象复制到已使用足够大的对象bytes初始化的可共享列表中。bytes当bytes我复制的对象有尾随零(即最终值为0x00)时,共享内存列表中的新条目缺少这些零。数据中间的零不会导致提前截断。下面是一个带有输出的最小示例。
代码:
from multiprocessing import shared_memory as shm
shmList = shm.ShareableList([bytes(50)])
testBytes = bytes.fromhex("00112233445566778899aabbccddeeff0000")
shmList[0] = testBytes
print(testBytes)
print(shmList[0])
shmList.shm.close()
shmList.shm.unlink()
Run Code Online (Sandbox Code Playgroud)
输出:
b'\x00\x11"3DUfw\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x00\x00'
b'\x00\x11"3DUfw\x88\x99\xaa\xbb\xcc\xdd\xee\xff'
Run Code Online (Sandbox Code Playgroud)
我希望该bytes对象将被完整复制,包括尾随零。这看起来像是一个“功能”:sourcecode,但为什么呢?
有没有简单的解决方法?
我已经在我的 C 程序中初始化了一个结构并将其附加到共享内存。结构如下:
#define DrvMaxTag 1024
#define DrvMaxStr 128
#define StructLEN 32
typedef struct TagTypeStruct
{
unsigned char IO;
unsigned char Drv;
unsigned char Class;
unsigned char Group;
}TagTypeStruct;
typedef struct IEC_DT
{
long int tv_Sec;
long int tv_nSec;
}IEC_DT;
typedef struct DrvSHMTagStruct
{
char TagName[DrvMaxTag][DrvMaxStr];
double TagValue[DrvMaxTag];
double OldValue[DrvMaxTag];
unsigned int TagStatus[DrvMaxTag];
unsigned int OldStatus[DrvMaxTag];
long long TagControl[DrvMaxTag];
IEC_DT TagValueDT[DrvMaxTag];
TagTypeStruct TagType[DrvMaxTag];
int DrvAddr[DrvMaxTag];
unsigned char LogFlag[DrvMaxTag];
unsigned char Freeze[DrvMaxTag];
int LogicState;
char DrvPath[DrvMaxStr];
int TagQuantity;
unsigned char Instance; …Run Code Online (Sandbox Code Playgroud) 我正在尝试理解命令pipe(2),例如:
int pipefd[2];
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
Run Code Online (Sandbox Code Playgroud)
我希望得到两个文件描述符shared memory,用于匿名管道(父子关系).
例如,这是父子进程之间的简单对话:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#define SHMSIZE 16
int main() {
int shmid;
char *shm;
if(fork() == 0) // child first
{
shmid = shmget(2009, SHMSIZE, 0);
shm = shmat(shmid, 0, 0);
char *s = (char *) shm;
*s = '\0';
int i;
// child enters the input that would be stored in …Run Code Online (Sandbox Code Playgroud)