2014-08-28 3 views
0

Прежде всего, я уверен, что есть более быстрые и менее переполненные решения, но мне абсолютно необходимо заполнить массив только дочерними процессами.Заполните массив с помощью fork()

Скажем, у меня есть 3 Чайлдс:

int pos = 0; 
    for (i = 0; i<3 ; i++){ 
switch (fork()){ 

    case -1: //fork error; 
     printf("[ERROR] - fork()\n"); 
     exit(EXIT_FAILURE); 

    case 0: //child 
     fill(&req, pos); 
     pos++; 
     exit(EXIT_SUCCESS); 

    default: 
     break; 
} 

}

где заполняют в основном работает следующим образом:

void fill (request *req, int pos){ 
    req->array[pos] = 1; 
    } 

я понял, этот метод, конечно, не работает, так как каждый у ребенка есть копия pos = 0, и они просто увеличивают свою копию, поэтому массив всегда изменяется на 0. . Запрос структуры представляет собой структуру simpe с pid и массивом int отправляем через fifo.

typedef struct request { 
    int cpid;  //client pid 
    int array[SIZE]; //array 
    } request; 

Что я могу сделать, чтобы заполнить этот массив только дочерними процессами? Я должен повторить, я не могу использовать обходные пути, просто fork() и childs. Спасибо!

+0

Вы знаете, что разветвленный процесс не разделяет память с родителем или с другими его братьями и сестрами? – Art

+0

Да, как я писал после метода заполнения, я понял, что это невозможно, поскольку они копируют значение pos. –

+1

Вам «абсолютно необходимо» использовать механизм, который не может делать то, что вам нужно (по крайней мере, не без большой настройки самой системы). Зачем? В чем смысл? Кто-то дал вам молоток и попросил вас использовать его только для полировки окна? Я вообще не понимаю вопроса. Ответ: «вы не можете этого сделать, как вы уже разобрались». – Art

ответ

0

Вы не можете изменить некоторые данные (для совместных) после fork, потому что каждый process имеет ие определении как его собственныхaddress space, следовательно, любые изменений в данные частного к этому процессу (если не использовать общую память).

Вы можете использовать shared memory, который вы должны установить перед вызовом fork(2). Тогда у вас проблемы с синхронизацией. Поэтому читайте shm_overview(7) и sem_overview(7); в вашем случае, я чувствую, что это слишком много.

Вы также можете использовать threads, а не процессы. В некоторых процессах есть несколько потоков, все разделяющие - по определению - одно и то же общее адресное пространство. Опять же, синхронизация является проблемой (например, с mutexes). Ознакомьтесь с некоторыми pthread tutorial

Вы можете использовать некоторые другие IPC, например. pipe(7) -s. Вероятно, вам понадобится мультиплексный системный вызов, например poll(2).

(я думаю, может быть, неправильно, что весь смысл этой домашней работы, чтобы научить вас о трубах и event loops, если вы используете трубы, лучше принять некоторые textual protocol)

Read Advanced Linux Programming.

Кстати, на fork и другие системные вызовы ошибки, вам следует позвонить perror(3) -не простой printf как вы DO- затем exit(EXIT_FAILURE).

+0

Ваша догадка о том, что это правильно, это проект о IPC и Unix в целом. Определенно идет для shm и sems. Спасибо за отзыв об ошибках, это был всего лишь фрагмент кода, в будущем мне обязательно понадобятся обработчики ошибок. –

1

Если дети - это те, кто должен заполнить массив, то их изменения не могут быть видны родителям или любому другому ребенку, если родитель и ребенок не имеют некоторую память (shmget).

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

+1

Поскольку каждый разветвленный процесс имеет * собственное * адресное пространство. –

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