我有两个 C 程序需要相互通信。我在一个程序中使用 shmget(key, 27, IPC_CREAT | 0666) 将一个变量存储在共享内存中。我每 1 秒更新一次这个变量。在另一个程序中,我使用 shmget(key, 27, 0666) 每 1 秒访问一次它。
这非常有效,但一段时间后(通常是几个小时),检索数据的程序会因段错误而崩溃。我使用 gdb 将段错误查明到 shmget(key, 27, 0666) 行。返回的错误代码为:
ENOMEM 无法为描述符或页表分配内存。
当我使用 ipcs -m 从命令提示符检查共享内存段时,我当前看到以下内容:
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x00000000 65536 root 600 393216 2 dest
0x00000000 98305 root 600 393216 2 dest
0x00000000 131074 root 600 393216 2 dest
0x00000000 163843 root 600 393216 2 dest
0x00000000 196612 root 600 393216 2 dest
0x00000000 229381 root …Run Code Online (Sandbox Code Playgroud) 我正在process-1尝试将数据写入共享内存。同时process-2我正在从同一共享内存中读取数据。在这种情况下,我需要在这两个进程之间提供同步。如果我要遍历未命名的信号量(使用shm_init(),mmap()),它会起作用吗?
我写了这样的代码,它能工作吗?
fd = shm_open("shm_name", O_CREAT| O_RDWR, S_IRUSR | S_IWUSR);
sema = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE,MAP_SHARED , fd, 0);
sem_init(sema, 1, 1);
Run Code Online (Sandbox Code Playgroud) 我是一个使用共享内存的初学者,我已经实现了一个并行加法器,其中每个 k 处理器都作为子进程实现。具体来说,给定一组 n 个整数和 k 的值,主程序创建 k 个子进程,分配每个子进程计算其指定的 n/k 个数字上限的总和,等待 k 个数字中每一个的小计子进程,对小计进行求和,并打印每个小计的结果以及总和。我没有使用线程。
该程序是为学院中的作业而创建的,预计可以在任何部门的计算机上运行。
该代码在 Kali Linux 上可以正确编译,但无法在其他 Linux 版本上编译和运行。当我尝试在 Ubuntu 上编译时,出现错误:
对“sem_init”的未定义引用
我在编译行中使用了 -lrt 。请帮我解决这个问题。
这是我创建的代码。
#include<stdio.h>
#include<sys/ipc.h>
#include<sys/wait.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<errno.h>
#include<semaphore.h>
#include<unistd.h>
#include<math.h>
#include<stdlib.h>
#define BUFFER_SIZE 100
#define BUFFER_SUB 2
typedef struct
{
int bufMax;
int datalimit;
int buff[BUFFER_SIZE];
sem_t mutex, empty, full;
} shared_inputs;
typedef struct
{
int sub[BUFFER_SUB];
sem_t mutex,empty,full;
}sub_tot;
int main(int argc, char *argv[])
{
int x = 0;
int data,count,i,j,tot;
int …Run Code Online (Sandbox Code Playgroud) 所以我需要为Linux编写文件映射(Windows OpenFileMapping(),MapViewOfFile()等等)。我就是QSharedMemory为了这个而选择的。但我不确定如何让它与全局内存一起工作。
是否有另一个正确的 Linux 文件映射模拟或功能QSharedMemory?
多个线程在 CPU 的多个核心上并行运行。他们可以同时访问主存储器吗?
multithreading cpu-architecture shared-memory hardware-acceleration
全面披露:虽然这不是针对课程的,但它是一个简化的示例,涉及我之前的作业(现已通过)中遇到的问题。
考虑使用 POSIX 共享内存在两个进程之间传输文件。生产者进程共享从文件中读取的内容,并将其按块写入共享内存区域;消费者进程从该区域读取一大块字节并将其写出(例如写入文件)。起初,我尝试了一种简单的同步方法 - 只是锁定对信号量中共享内存的访问 - 但当然,这允许单个写入/读取的多个读取/写入。
我想我已经找到了一种方法来做到这一点,即使用第二个共享内存区域,根据其当前值阻止对读取器或写入器的访问。然后,用伪代码:
before request begins:
initialize shared memory region SHM
initialize synchronization region SHM2 = "0"
initialize sem
consumer:
loop until total bytes read = file length:
while (SHM2 == "0" [lock access to SHM2 while checking]):
wait
read N bytes from SHM
write N bytes to file
sem_wait(sem)
set SHM2 = "0"
sem_post(sem)
producer:
loop until total bytes written = file length:
while (SHM2 == "1" [lock access to SHM2 while checking]): …Run Code Online (Sandbox Code Playgroud) 假设一个进程创建了一块大小为 2 个整数(64 位/8 字节)的共享内存。
共享内存不仅可供进程的线程使用,还可供系统上有权访问该共享内存的其他进程使用。
据推测,第一个进程中的共享内存将通过虚拟地址空间进行寻址,因此当对第 1 个整数执行原子操作(cmp 交换)时,将使用第一个处理的上下文中的虚拟地址。
如果另一个进程同时对第一个整数执行某种原子操作,它也将使用自己的虚拟地址空间。
那么什么系统实际上执行到实际物理地址的转换,并且从非常一般的 POV 来看,CPU 在这种情况下如何提供原子性保证?
我用python.multiprocessing.sharedctypes.RawArray在多个进程之间共享大型 numpy 数组。我注意到,当这个数组很大(> 1或2 Gb)时,初始化会变得非常慢,读/写也会慢得多(并且读/写时间不可预测,有时非常快,有时非常非常慢)慢的)。
我制作了一个小型示例脚本,它仅使用一个进程,初始化一个共享数组并对其进行多次写入。并测量执行这些操作的时间。
import argparse
import ctypes
import multiprocessing as mp
import multiprocessing.sharedctypes as mpsc
import numpy as np
import time
def main():
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument('-c', '--block-count', type=int, default=1,
help='Number of blocks to write')
parser.add_argument('-w', '--block-width', type=int, default=20000,
help='Block width')
parser.add_argument('-d', '--block-depth', type=int, default=15000,
help='Block depth')
args = parser.parse_args()
blocks = args.block_count
blockwidth = args.block_width
depth = args.block_depth
start = time.perf_counter()
shared_array = mpsc.RawArray(ctypes.c_uint16, blocks*blockwidth*depth)
finish = time.perf_counter()
print('Init shared array of size {:.2f} …Run Code Online (Sandbox Code Playgroud) 我从userfaultfd的文档中看到
https://manpages.debian.org/testing/manpages-dev/userfaultfd.2.en.html http://man7.org/linux/man-pages/man2/ioctl_userfaultfd.2.html
userfaultfd 从内核 4.11 开始支持共享映射。然而,文档看起来仍然非常模糊,因为我仍然想知道这些是否包括支持文件支持的 mmap(也可以是 MAP_SHARED)?
linux memory-management shared-memory memory-mapped-files linux-kernel
我想知道是否可以获取 C 语言中创建的共享内存段的大小,而shmget无需将该段的大小作为数据的一部分?我正在尝试分配一个动态 int 数组,并且需要在子进程中查找数组的大小。
主要流程:
int sizeOfArray = 3;
int shm = shmget(IPC_PRIVATE, sizeof(int) * sizeOfArray, IPC_CREAT | 0666);
int *a = (int*) shmat(shm, NULL, 0);
a[0] = 0;
a[1] = 1;
a[2] = 2;
if (fork() == 0) {
char *args[3];
char shmID[11];
bzero(shmID, 11);
intToString(shm, shmID); // custom function that does what the name implies
args[0] = "slave";
args[1] = shmID;
args[2] = NULL;
execvp("slave", args);
return -1;
}
wait(NULL);
shmdt((void*) a);
shmctl(shm, IPC_RMID, NULL); …Run Code Online (Sandbox Code Playgroud) shared-memory ×10
c ×6
linux ×4
semaphore ×3
c++ ×2
ipc ×2
atomic ×1
linux-kernel ×1
numpy ×1
performance ×1
posix ×1
pseudocode ×1
python ×1
qt ×1