Python多线程与多进程
一、python多线程
python中提供标准库threading用于对线程的支持
1、创建线程
python中有两种方式实现线程:
1.实例化一个threading.Thread的对象,并传入一个初始化函数对象(initial function )作为线程执行的入口;
import threading
import time
def tstart(arg):
time.sleep(0.5)
print("%s running...." % arg)
if__name_== __main__:
t1 = threading.Thread(target=tstart, args=('This is thread 1',))
t2 = threading.Thread(target=tstart, args=('This is thread 2',))
t1.start()
t2.start()
print("This is main function")
2.继承threading.Thread,并重写run函数;
import threading
import time
class CustomThread(threading.Thread):
def __init__(self, thread_name):
# step 1: call base __init__ function
super(CustomThread, self).__init__(name=thread_name)
self._tname = thread_name
def run(self):
# step 2: overide run function
time.sleep(0.5)
print("This is %s running...." % self``._tname)
if __name__ == "__main__":
t1 = CustomThread("thread 1")
t2 = CustomThread("thread 2")
t1.start()
t2.start()
print("This is main function")
2、多线程执行
在主线程中创建若线程之后,他们之间没有任何协作和同步,除主线程之外每个线程都是从run开始被执行,直到执行完毕。
join
我们可以通过join方法让主线程阻塞,等待其创建的线程执行完成。
import threading
import time
def tstart(arg):
print("%s running....at: %s" % (arg,time.time()))
time.sleep(1)
print("%s is finished! at: %s" % (arg,time.time()))
if __name__ == '__main__':
t1 = threading.Thread(target=tstart, args=('This is thread 1',))
t1.start()
t1.join() # 当前线程阻塞,等待t1线程执行完成
print("This is main function at:%s" % time.time())
如果不加任何限制,当主线程执行完毕之后,当前程序并不会结束,必须等到所有线程都结束之后才能结束当前进程。
可以通过将创建的线程指定为守护线程(daemon),这样主线程执行完毕之后会立即结束未执行完的线程,然后结束程序。
deamon守护线程
import threading
import time
def tstart(arg):
print("%s running....at: %s" % (arg,time.time()))
time.sleep(``1``)
print("%s is finished! at: %s" % (arg,time.time()))
if __name__ =``= '__main__'``:
t1 = threading.Thread(target=tstart, args=('This is thread 1',))
t1.setDaemon(True)
t1.start()
# t1.join() # 当前线程阻塞,等待t1线程执行完成
print("This is main function at:%s" % time.time())
二、python多进程
相比较于threading模块用于创建python多线程,python提供multiprocessing用于创建多进程。先看一下创建进程的两种方式。
1、创建进程
创建进程的方式和创建线程的方式类似:
1.实例化一个multiprocessing.Process的对象,并传入一个初始化函数对象(initial function )作为新建进程执行入口;
from multiprocessing import Process
import os, time
def pstart(name):
# time.sleep(0.1)
print("Process name: %s, pid: %s "%(name, os.getpid()))
if __name__ == "__main__":
subproc = Process(target=pstart, args=('subprocess',))
subproc.start()
subproc.join()
print("subprocess pid: %s"%subproc.pid)
print("current process pid: %s" % os.getpid())
2.继承multiprocessing.Process,并重写run函数;
from multiprocessing import Process
import os, time
class CustomProcess(Process):
def __init__(self, p_name, target=None):
# step 1: call base __init__ function()
super(CustomProcess, self).__init__(name=p_name, target=target, args=(p_name,))
def run(self):
# step 2:
# time.sleep(0.1)
print("Custom Process name: %s, pid: %s "%(self.name, os.getpid()))
if __name__ == '__main__':
p1 = CustomProcess("process_1")
p1.start()
p1.join()
print("subprocess pid: %s"%p1.pid)
print("current process pid: %s" % os.getpid())
三、线程与进程区别
下面简单的比较一下线程与进程
- 进程是资源分配的基本单位,线程是CPU执行和调度的基本单位;
通信/同步方式:
进程:
- 通信方式:管道,FIFO,消息队列,信号,共享内存,socket,stream流;
- 同步方式:PV信号量,管程
线程:
- 同步方式:互斥锁,递归锁,条件变量,信号量
- 通信方式:位于同一进程的线程共享进程资源,因此线程间没有类似于进程间用于数据传递的通信方式,线程间的通信主要是用于线程同步。
- CPU上真正执行的是线程,线程比进程轻量,其切换和调度代价比进程要小;
- 线程间对于共享的进程数据需要考虑线程安全问题,由于进程之间是隔离的,拥有独立的内存空间资源,相对比较安全,只能通过上面列出的IPC(Inter-Process Communication)进行数据传输;
- 系统有一个个进程组成,每个进程包含代码段、数据段、堆空间和栈空间,以及操作系统共享部分 ,有等待,就绪和运行三种状态;
- 一个进程可以包含多个线程,线程之间共享进程的资源(文件描述符、全局变量、堆空间等),寄存器变量和栈空间等是线程私有的;
- 操作系统中一个进程挂掉不会影响其他进程,如果一个进程中的某个线程挂掉而且OS对线程的支持是多对一模型,那么会导致当前进程挂掉;
- 如果CPU和系统支持多线程与多进程,多个进程并行执行的同时,每个进程中的线程也可以并行执行,这样才能最大限度的榨取硬件的性能;
还没有评论,来说两句吧...