多线程进程fork出来的进程是单线程还是多线程?

开发 前端
一个多线程进程fork出来的进程是多线程还是单线程的?先说结论:是单线程的。

本文转载自微信公众号【编程珠玑】(shouwangxiansheng)。

一个多线程进程fork出来的进程是多线程还是单线程的?先说结论:是单线程的。

[[405231]]

实践

口说无凭,我们先写段代码实践验证一下。

  1. // multiThread.cc 
  2. #include <unistd.h> 
  3. #include <atomic> 
  4. #include <chrono> 
  5. #include <iostream> 
  6. #include <thread> 
  7. std::atomic<bool> start{false}; 
  8. void threadfunc() { 
  9.   while (!start) { 
  10.     std::this_thread::sleep_for(std::chrono::seconds(1)); 
  11.   } 
  12.   while (start) { 
  13.     std::this_thread::sleep_for(std::chrono::seconds(1)); 
  14.     std::cout << "thread func,pid:" << getpid() << std::endl
  15.   } 
  16. int main() { 
  17.   std::thread t1(threadfunc); 
  18.   // daemon(0, 1); // 后台执行 
  19.   start.store(true); 
  20.   t1.join();  // 等待threadfunc运行结束 
  21.   return 0; 

编译运行:

  1. $ g++ -o multiThread multiThread.cc -lphtread 
  2. $ ./multiThread 
  3. thread func,pid:9901 
  4. thread func,pid:9901 
  5. thread func,pid:9901 

结果正常,线程不断循环打印信息。那如果启动线程后,再fork呢?即将代码中daemon的相关行的注释去掉,再编译运行。

运行这个例子,我们会发现,程序立马退出了,没有打印我们预想的内容。

为什么

为什么会这样呢?实际上,fork的时候会拷贝父进程的数据内容,即写时复制,但是,像启动运行的线程,是不会被“复制”过去的。也就是说,从父进程fork出来的子进程,将会是单线程的。这也就给了我们一些启示:

如果在API中需要启动工作线程,则工作线程需要在daemon化之后再启动。

怎么理解呢?比如说,你设计了某一个功能,你的功能是需要启动一个线程来进程工作,那么你在使用的时候,就必须要特别注意这种fork进程的场景,即需要在fork之后启动线程,才能保证线程能够正常启动并工作。

 

责任编辑:赵宁宁 来源: 编程珠玑
相关推荐

2024-09-27 11:51:33

Redis多线程单线程

2020-11-09 09:33:37

多线程

2019-02-26 11:15:25

进程多线程多进程

2019-10-29 20:13:43

Java技术程序员

2023-08-17 14:12:17

2021-01-28 11:17:49

Python爬虫单线程

2023-12-01 08:18:24

Redis网络

2020-09-23 13:37:25

Redis6.0

2022-05-26 08:31:41

线程Java线程与进程

2013-12-02 17:33:20

Linux进程多线程

2022-07-18 13:59:43

Redis单线程进程

2022-03-09 17:01:32

Python多线程多进程

2020-11-17 10:20:53

Redis多线程单线程

2023-12-13 09:56:13

​多进程多线程协程

2018-01-11 08:24:45

服务器模型详解

2009-07-10 09:05:20

SwingWorker

2012-06-20 14:07:28

多线程架构单线程

2019-06-03 09:13:11

线程进程多线程

2021-09-10 21:25:43

Redis分布式

2021-08-04 23:30:28

Node.js开发线程
点赞
收藏

51CTO技术栈公众号