使用 mmap 添加到结构数组

Add to an array of structs using mmap

我想通过 fork 分派一些任务,并在数组中收集有关这些任务结果的一些信息。

我的想法是使用 mmap 在两者之间共享一个数据结构,并让子进程使用 activity 的结果更新结构数组,但我遇到了一些问题。

#include <time.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/mman.h>
#include <stdlib.h>


typedef struct message_s {
    int status;
    char message[256];
} message_t;


void child(message_t **result) {


    result[0]->status = 2;
    sprintf((char *) &result[0]->message, "Hello World!");
    usleep(1);

}

void parent() {
    printf("Parent\n");
    usleep(1);
    return;
}


int main() {
    size_t result_size = 1000 * sizeof(message_t);


    message_t **result_ar = mmap(NULL, result_size,
                                 PROT_READ | PROT_WRITE,
                                 MAP_SHARED | MAP_ANON, -1, 0);


    pid_t child_pid = fork();

    switch (child_pid) {
        case 0:
            child(result_ar);
            exit(0);

        case -1:
            exit(-1);
            break;
        default:
            parent();
    }

    int child_status;
    waitpid(child_pid, &child_status, 0);


    printf("\nRESULT: %i: %s\n\n", result_ar[0]->status, result_ar[0]->message);

    msync(result_ar, result_size, MS_SYNC);
    munmap(result_ar, result_size);

    return 0;
}

我真的有点迷路了,虽然我可以在 SO 上找到 "similar" 个问题,但他们要么没有答案,要么被其他问题困扰,或者两者兼而有之。

当上面的代码运行时,我得到以下串联结果。

Process:               concurrent_test [2537]
Path:                  /Users/USER/Library/Caches/*/concurrent_test
Identifier:            concurrent_test
Version:               0
Code Type:             X86-64 (Native)
OS Version:            Mac OS X 10.10.5 (14F1509)
Report Version:        11

Crashed Thread:        0  Dispatch queue: com.apple.main-thread

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000000

VM Regions Near 0:
--> 
    __TEXT                 000000010144a000-000000010144c000 [    8K] r-x/rwx SM=COW  /Users/USER/Library/Caches/*

Application Specific Information:
crashed on child side of fork pre-exec

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   concurrent_test                 0x000000010144bb33 child + 35
1   concurrent_test                 0x000000010144bc1f main + 127
2   concurrent_test                 0x000000010144b5a9 _start + 247
3   concurrent_test                 0x000000010144b4b1 start + 33

Thread 0 crashed with X86 Thread State (64-bit):
  rax: 0x0000000000000000  rbx: 0x00007fff5e7b5908  rcx: 0x000000010144beb3  rdx: 0xffffffffffffffff
  rdi: 0x0000000000000000  rsi: 0x0000000000000000  rbp: 0x00007fff5e7b5730  rsp: 0x00007fff5e7b5720
   r8: 0x0000000000000303   r9: 0x0000000000000000  r10: 0x0000000000000030  r11: 0x0000000000000206
  r12: 0x00007fff5e7b57e0  r13: 0x0000000000000000  r14: 0x00007fff5e7b57f0  r15: 0x0000000000000001
  rip: 0x000000010144bb33  rfl: 0x0000000000010246  cr2: 0x0000000000000000

Logical CPU:     6
Error Code:      0x00000006
Trap Number:     14

我正在使用:

Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin14.5.0
Thread model: posix

您的代码中有一个间接寻址过多。尝试 message_t *result_ar = mmap(...);result[0].status = 2; 来解决这个问题。另外,不要忘记错误检查! mmap() 可能会失败。