进程与线程#
- 进程
具有其它应用程序无法访问的内存空间的应用程序运行状态,创建 Python 进程的一个例子是运行一个简单的 "hello world" 应用程序,或在命令行输入 Python 来启动 REPL(交互式环境)。
多个进程可以在一台机器上运行,如果有一台拥有多核 CPU 的机器,就可以同时执行多个进程。在只有一个核的 CPU 上,仍可通过时间片,同时运行多个应用程序。当操作系统使用时间片时,它会在一段时间后自动切换下一个进程并运行它。确定何时发生此切换的算法因操作系统而异。
- 线程
可以被认为是轻量级进程,此外线程是操作系统可以管理的最小结构,它们不像进程那样有自己的内存空间,相反,它们共享进程的内存。线程与创建它们的进程关联,一个进程总是至少有一个与之关联的线程,通常称为主线程。一个进程还可以创建其他线程,通常称为工作线程或后台线程,这些线程可与主线程同时执行其他工作。线程很像进程,可以在多核 CPU 上并行运行,操作系统也可通过时间片在它们之间切换。当运行一个普通的 Python 应用程序时,会创建一个进程以及一个负责执行具体代码的主线程。
备注
进程是操作系统分配资源的最小单元,线程是操作系统用来调度 CPU 的最小单元。进程好比一个房子,而线程是房子里面干活的人,所以一个进程里面可以有多个线程,线程共享进程里面的资源。因此真正用来工作的是线程,进程只负责提供相应的内存空间和资源。
线程#
import os
import threading
print(f"进程启动,pid 为 {os.getpid()}")
print(f"该进程内部运行 {threading.active_count()} 个线程")
print(f"当前正在运行的线程是 {threading.current_thread().name}")
print(f"当前线程的线程标识符 {threading.get_ident()}")
print(f"内核分配给当前线程的原生集成线程 ID {threading.get_native_id()}")
进程启动,pid 为 3237
该进程内部运行 7 个线程
当前正在运行的线程是 MainThread
当前线程的线程标识符 140602012834688
内核分配给当前线程的原生集成线程 ID 3237
当前所有存活的 Thread
对象的列表:
threading.enumerate()
[<_MainThread(MainThread, started 140602012834688)>,
<Thread(IOPub, started daemon 140601909577408)>,
<Heartbeat(Heartbeat, started daemon 140601890703040)>,
<Thread(Thread-2 (_watch_pipe_fd), started daemon 140601754388160)>,
<Thread(Thread-3 (_watch_pipe_fd), started daemon 140601590810304)>,
<ControlThread(Control, started daemon 140601571935936)>,
<ParentPollerUnix(Thread-1, started daemon 140601553061568)>]
threading.main_thread()
返回主 Thread
对象。一般情况下,主线程是 Python 解释器开始时创建的线程。
threading.main_thread()
<_MainThread(MainThread, started 140602012834688)>
进程可创建新的线程,这些线程可通过所谓的多线程技术同时完成其他工作,并共享进程的内存。
import threading
def hello_from_threading():
print(f"Hello {threading.current_thread().name} 线程")
hello_thread = threading.Thread(target=hello_from_threading, name="new-thread")
hello_thread.start()
print(f"该进程内部运行 {threading.active_count()} 个线程")
print(f"当前正在运行的线程是 {threading.current_thread().name}")
hello_thread.join()
Hello new-thread 线程
该进程内部运行 7 个线程
当前正在运行的线程是 MainThread
进程#
import multiprocessing as mp
import os
def hello_from_process():
print(f"当前子进程的 pid 为 {os.getpid()}")
# 在 Windows 上必须加上 if __name__ == '__main__'
# 否则多进程乎启动失败
if __name__ == '__main__':
hello_process = mp.Process(target=hello_from_process)
hello_process.start()
hello_process.join()
当前子进程的 pid 为 3255