#c #multithreading #multiprocessing #fork
#c #многопоточность #многопроцессорная обработка #форк
Вопрос:
Я пытаюсь изучить многопроцессорность и то, как она работает по сравнению с многопоточностью. Мне трудно найти хороший источник его использования, и мне было интересно, может ли кто-нибудь привести мне несколько примеров по сравнению с многопоточностью.
Для практики я решил попробовать написать код с потоками, а затем с процессами. Я застрял на том, чтобы выяснить, как создавать процессы, которые я хочу, закрывать процессы и использовать мьютекс для блокировки / разблокировки процесса.
Например, если я хочу создать 5 потоков в функции, я могу сделать это:
for(i = 0; i < 5; i ) {
pthread_create(amp;(myThread[i]), NULL, myFunction, argument);
}
Как бы я это сделал в процессе? Я рассматривал возможность вызова функции, а затем вызова fork в функции, но я не уверен, как получить конкретное число. Например, если бы я сделал это:
myFunction(argument) {
fork();
fork();
fork();
...
}
Это дало бы мне всего 8 процессов. Слишком много. Но если бы я удалил fork() , у меня было бы всего 4 процесса, что слишком мало. Как мне создать ровно столько процессов, сколько я хочу?
Далее, если бы я должен был закрыть потоки, я бы просто сделал это:
for(i = 0; i < 5; i ){
pthread_join(myThread[i],NULL);
}
Но как бы я это сделал для процессов?
Наконец, для обеспечения безопасности потоков я могу использовать мьютекс и разблокировать блокировку вызова, когда это необходимо.
static pthread_mutex_t my_mutex;
pthread_mutex_lock(amp;my_mutex);
...
pthread_mutex_unlock(amp;my_mutex);
Могу ли я использовать мьютексы с процессом? Если нет, то какая альтернатива есть? Если да, то как будет отличаться его реализация?
Ответ №1:
Вы должны проверять возвращаемое значение при вызове fork
. Например:
for (int i = 0; i < 4; i)
{
pid_t child = fork();
if(pid == -1) perror("wtf? "), abort(); // failed!
if(!pid) {
// in child process ...:
do_work();
exit(0);
}
}
-1
Возвращаемое значение указывает на ошибку, в то время 0
как указывает, что вы находитесь внутри дочернего процесса.
Если вы находитесь в дочернем процессе, либо разорвите цикл, либо продолжайте выполнять некоторую работу перед выходом из процесса.
Обратите внимание, что нет необходимости в управлении мьютексами, поскольку родительский процесс и дочерние процессы не используют одну и ту же память. Это также означает, что им нужно будет взаимодействовать другими способами (часто с использованием каналов, сокетов unix или специально выделенной общей памяти).
Комментарии:
1. Но если родители и дочерние элементы читают и записывают в один и тот же файл в коде, наверняка это потребует некоторой защиты, не так ли?
2. Файлы имеют блокировки ОС при записи в них, но да , вам определенно нужно учитывать эти проблемы. Многопоточность отличается от многопоточности, и у каждого есть свои преимущества и недостатки.
3. @Tarface если несколько процессов используют один и тот же файл, они могут координировать свои действия с помощью блокировки файла с помощью
fcntl()
илиflock()
.4. @Tarface — если вы нашли ответ полезным, не стесняйтесь поддержать или принять ответ.
5. @Tarface, пожалуйста, обратите внимание : обычно это небезопасно для
fork
многопоточного процесса . Например, другие потоки могут находиться в критической секции (т. Е. Внутри вызоваmalloc
orprintf
), оставляя дочерний процесс в плохой ситуации.
Ответ №2:
Как мне создать ровно столько процессов, сколько я хочу?
Используйте exec
семейство API.
Но как бы я это сделал для процессов?
wait
заблокирует текущий процесс до завершения дочернего процесса.