进程
什么是进程?
进程是操作系统进行资源分配和调度的最小单位,可以认为一个运行的程序就是一个进程,比如:qq,微信等
什么是多进程,为什么要使用多进程?
运行程序时,程序会默认创建一个主进程,代码会从上到下依次运行;如果在代码运行时又创建了一个或多个进程(子进程),那么这就是多进程,可同时实现多个任务,使执行更加高效。
import multiprocessing
import os
def test():
#os.getpid()获取当前进程编号
print("子进程",os.getpid())
if __name__ == '__main__':
#创建了一个子进程
process1=multiprocessing.Process(target=test)
#启动进程
process1.start()
print("主进程",os.getpid())
主进程 24764
子进程 43248
子进程是由主进程程创建的 ,getppid()可以获取父进程编号
import multiprocessing
import os
def test():
#os.getppid()获取父进程编号
print("子进程",os.getppid())
if __name__ == '__main__':
#创建了一个子进程,target的参数指要创建进程的函数名(这里我将一个函数作为新的进程)
process1=multiprocessing.Process(target=test)
#启动进程
process1.start()
#获取主进程的编号
print("主进程",os.getpid())
主进程 42384
子进程 42384
当然还可以给进程传入参数 ,args()表示以元组的方式给函数传参,还有字典( kwargs={})的方式
import multiprocessing
def test(parameter):
#os.getppid()获取父进程编号
print(parameter)
if __name__ == '__main__':
#创建了一个子进程
process1=multiprocessing.Process(target=test,args=("函数先生,这是以创建进程的方式给你传得参数",))
#启动进程
process1.start()
函数先生,这是以创建进程的方式给你传得参数
进程的结束顺序,以及对控制进程
进程的结束顺序
在现实生活中我们在使用微信时,可以开好多小窗口,只要将qq主程序结束掉,那么小窗口也会消失,但在程序中是这样的吗,还是实现这种效果需要进行控制呢?
def test():
for i in range(6):
print("work")
if __name__ == '__main__':
#创建了一个子进程
process1=multiprocessing.Process(target=test)
#启动进程
process1.start()
print("主进程执行完了")#表示主进程结束了
主进程执行完了
work
work
work
work
work
work
Process finished with exit code 0
我们可以发现,主进程并没有结束,而是在等待子进程,并且子进程结束后再结束
控制进程
1、设置守护进程
import multiprocessing
import time
def test():
for i in range(6):
print("work")
time.sleep(0.05)#睡眠0.05秒
if __name__ == '__main__':
#创建了一个子进程
process1=multiprocessing.Process(target=test)
#设置守护进程,随主进程结束而结束
process1.daemon=True
#启动进程
process1.start()
time.sleep(0.2)#睡眠0.2秒,使结果更加明显
print("主进程执行完了")#表示主进程结束了
work
work
主进程执行完了
Process finished with exit code 0
2、销毁子进程
def test():
for i in range(6):
print("work")
time.sleep(0.05)#睡眠0.05秒
if __name__ == '__main__':
#创建了一个子进程
process1=multiprocessing.Process(target=test)
#启动进程
process1.start()
time.sleep(0.2)#睡眠0.2秒,使结果更加明显
print("主进程执行完了")#表示主进程结束了
process1.terminate()#将子进程销毁
work
work
主进程执行完了
Process finished with exit code 0
线程
什么是线程?
线程是分配资源的最小单位,我们可以理解为将进程是线程的容器,线程可以使用进程的全部资源。在生活中,我们打开的微信可以作为进程,打开的多个微信窗口就可以认为是多个线程。
多线程实现多任务
线程可以共享进程中的资源,多个线程可以将依次执行的程序拆分成多个程序一起执行,提高了进程的执行效率
创建多线程的方式
可以使用threading模块中的Thread()方法(这里我将一个函数设为一个线程),传参和创建进程类似。
import threading
def thread1():
print("创建了一个线程")
def thread2():
print("创建了第二个线程")
if __name__ == '__main__':
one=threading.Thread(target=thread1)
two=threading.Thread(target=thread2)
one.start()
two.start()
创建了一个线程
创建了第二个线程
Process finished with exit code 0
线程的结束顺序和进程类似,可以参照进程
线程中的资源调度
线程共享全局变量
import threading
i=0#定义全局变量
def thread1():
print("创建了一个线程",i)
def thread2():
print("创建了第二个线程", i)
if __name__ == '__main__':
one=threading.Thread(target=thread1)
two=threading.Thread(target=thread2)
one.start()
two.start()
创建了一个线程 0
创建了第二个线程 0
Process finished with exit code 0
看一个列子,我们可以发现,两线程执行完后输出的都是100,这两个线程共享全局变量,不应该输出的是100和200吗?
import threading
g_num=0#定义全局变量
def thread1():
global g_num #修改全局变量需要global
for i in range(1000):
g_num=g_num+1
print("创建了一个线程",g_num)
def thread2():
global g_num
for i in range(100):
g_num = g_num + 1
print("创建了第二个线程",g_num)
if __name__ == '__main__':
one=threading.Thread(target=thread1)
two=threading.Thread(target=thread2)
one.start()
two.start()
创建了一个线程 100
创建了第二个线程 100
Process finished with exit code 0
如何解决进程问题呢?
互斥锁
对共享数据进行锁定,保证了统一时刻只有一个线程取操作,其他线程等待
互斥锁的使用
import threading
g_num=0#定义全局变量
def thread1():
mutex.acquire()#上锁
global g_num #修改全局变量需要global
for i in range(1000):
g_num=g_num+1
mutex.release() # 释放锁
print("创建了一个线程",g_num)
def thread2():
mutex.acquire() # 上锁
global g_num
for i in range(100):
g_num = g_num + 1
mutex.release() # 释放锁
print("创建了第二个线程",g_num)
if __name__ == '__main__':
mutex=threading.Lock()
one=threading.Thread(target=thread1)
two=threading.Thread(target=thread2)
one.start()
two.start()
创建了一个线程 1000
创建了第二个线程 1100
Process finished with exit code 0
注意:如果对线程上锁后没有释放锁容易造成死锁,进程会一直等待
线程和进程的对比
1、进程不共享全局变量而线程共享
2、进程是线程的容器,一个进程里可以创建多个线程
3、进程是操作系统资源分配的基本单位,线程CPU调度的最小单位
4、进程的资源开销比线程的大
5、进程使用多核,线程不能使用多核