2016-01-09 3 views
1

Я хотел бы отправить некоторые задачи через fork и собрать некоторую информацию о результатах этих задач в массиве.Добавьте к массиву структур с помощью mmap

Моя мысль заключается в том, чтобы использовать mmap для совместного использования структуры данных между ними, а дочерний процесс обновляет массив структур с результатом активности, но у меня возникают некоторые проблемы.

#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, они либо не имеют ответов или сталкиваются с другими проблемами, или оба.

Когда код выше работает, я получаю следующий конкатенированный результат.

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 

ответ

2

У вас есть один косвенность слишком много в вашем коде. Попробуйте message_t *result_ar = mmap(...); и result[0].status = 2;, чтобы устранить эту проблему. Кроме того, не забудьте проверить ошибку! mmap() может потерпеть неудачу.

+0

почти все может потерпеть неудачу, это (в основном) отсутствие проверки ошибок для краткости. Тем не менее, спасибо за отзыв, он полностью решает мою проблему! – lscoughlin

Смежные вопросы