I'm trying to learn multiprocessing and how it works compared to multithreading. I'm having a hard time finding a good source of its utilization and was wondering if anyone could give me some examples in comparison to multithreading.
For practice, I figured I'd try to write a code with threads, and then with processes. What I'm stuck on is figure out how to create the processes I want, close the processes, and use mutex to lock/unlock process.
For example, if I wanted to create 5 threads in a function, I can do this:
for(i = 0; i < 5; i++) {
pthread_create(&(myThread[i]), NULL, myFunction, argument);
}
How would I do this in a process? I've considered calling a function and then calling fork in the function, but I'm not sure how to get a specific number. For example if I did this:
myFunction(argument) {
fork();
fork();
fork();
...
}
That would give me 8 total process. Too many. But if I removed a fork(), I'd have 4 total processes, which is too few. How would I create exactly as many process as I want?
Next, if I were to close the threads, I'd just do this:
for(i = 0; i < 5; i++){
pthread_join(myThread[i],NULL);
}
But how would I do that for processes?
Finally, to keep threads safe, I can use mutex and call lock unlock when needed.
static pthread_mutex_t my_mutex;
pthread_mutex_lock(&my_mutex);
...
pthread_mutex_unlock(&my_mutex);
Could I use mutexes with process? If not, what alternative is there? If so, how would its implementation be different?
You should test for the return value when calling fork
. For example:
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);
}
}
A -1
return value indicates an error, while 0
indicates you're inside the child process.
If you're in the child process, either break the loop, or go on to perform some work before exiting the process.
Note that there's no need for mutex management, because the parent process and the children processes don't share the same memory. This also means that they will need to communicate in other ways (often using pipes, unix sockets or specially allocated shared memory).