C中的多线程与多处理

Posted

技术标签:

【中文标题】C中的多线程与多处理【英文标题】:Multithreading vs Multiprocessing in C 【发布时间】:2019-09-04 08:23:26 【问题描述】:

我正在尝试学习多处理以及与多线程相比它的工作原理。我很难找到一个很好的利用它的来源,并且想知道是否有人可以给我一些与多线程相比的例子。

为了练习,我想我会尝试用线程编写代码,然后再用进程编写代码。我坚持的是弄清楚如何创建我想要的进程,关闭进程,并使用互斥锁来锁定/解锁进程。

例如,如果我想在一个函数中创建 5 个线程,我可以这样做:

for(i = 0; i < 5; i++) 
    pthread_create(&(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);

但是我将如何为进程执行此操作?

最后,为了保证线程安全,我可以使用互斥体并在需要时调用 lock unlock。

static pthread_mutex_t my_mutex;
pthread_mutex_lock(&my_mutex);
...
pthread_mutex_unlock(&my_mutex);

我可以在进程中使用互斥锁吗?如果没有,还有什么替代方案?如果是这样,它的实现会有什么不同?

【问题讨论】:

【参考方案1】:

我将如何创建尽可能多的流程?

使用exec 系列 API。

但是我将如何为进程执行此操作?

wait 会阻塞当前进程,直到子进程退出。

【讨论】:

【参考方案2】:

您应该在调用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 套接字或专门分配的共享内存)。

【讨论】:

但是如果父母和孩子在代码中读写同一个文件,那肯定需要一些保护,不是吗? 文件在写入时具有操作系统锁,但是是的您肯定需要考虑这些问题。多处理与多线程不同,各有优缺点。 @Tarface 如果多个进程正在使用同一个文件,它们可以使用fcntl()flock() 通过文件锁定进行协调。 @Tarface - 如果您发现答案有帮助,请随时投票或接受答案。 @Tarface ,请注意:通常fork 多线程进程是不安全的。例如,另一个线程可能处于临界区(即,在对mallocprintf 的调用中),使子进程处于糟糕的境地。

以上是关于C中的多线程与多处理的主要内容,如果未能解决你的问题,请参考以下文章

python下的多线程与多进程

多线程与多进程的比较

QtConcurrent 与多线程 QThread 的多线程性能

为什么多线程通常与多处理相结合?

使用 openMP 进行多核处理与多线程

perl 的多线程与多进程