进程与线程相关
1.操作系统/应用程序
a.硬件
硬盘,CPU,主板,显卡,内存,电源...
b.软件,应用程序
QQ,pycharm,WPS
c.装系统(系统也是一个软件)
系统就是一个由程序员写出来的软件
2.并发和并行
并发:伪的,只是执行的速度特别快,人感觉不到停顿
并行:真的,几个工作同时进行
3.线程,进程
a.单进程,单线程的应用,
print(666)
b.什么是进程,什么是线程.
python自己没有,python中调用的是操作系统中的进程,和线程
c.单进程,多线程的应用程序
import threading
import time
print(666)
def task(arg):
print(arg)
arg=int(input('请输入一个数'))
t=threading.Thread(target=task,args=(arg,))
time.sleep(10)
t.start()
一个应用程序(软件),可以有多个进程(默认只有一个),一个进程中可以有多个线程(默认只有一个)
d.
以前:
import time
list=['思路.png','111.PNG','尚宏运.txt']
for row in list:
with open(row,mode='rb') as f:
time.sleep(5) #停顿五秒出来一个,一共停顿三个五秒
print(f.read())
(1)写好代码
(2)交给解释器取运行
(3)解释器读取代码,交给操作系统去执行,根据代码的内容,创建多少个线程/进程去执行(单进程/单线程)
(4)操作系统调用硬件
现在
import time
import threading
list=['思路.png','111.PNG','尚宏运.txt']
def task(arg):
with open(arg,mode='rb') as f:
time.sleep(5) #停顿一个五秒后全部都出来
print(f.read())
for arg in list:
t=threading.Thread(target=task,args=(arg,))
t.start()
(1)写好代码
(2)交给解释器去运行
(3)解释器读取代码,交给操作系统去执行 ,根据代码的内容,创建多少个进程/线程去执行(单进程/4线程)
(4)操作系统调用硬件
4. Python中线程和进程(GIL锁)
GIL锁,全局解释器锁,用于控制一个进程同一时刻,只有一个线程被CPU调度
GIL锁的存在限制了,在Python中,一个进程中,最多只能有一个线程工作
扩展:默认GIL锁在执行100个cpu指令。
import sys
v1 = sys.getcheckinterval()#(过期时间)
print(v1) 3执行100个CPU指令,就换另一个线程
python多线程情况下:
计算密集型操作:效率低
IO操作:效率高
python多进程情况下:
计算密集型操作:效率高 (浪费资源),不得已而为之
IO操作:效率高(浪费资源),更多用多线程解决
结论:以后的用法
IO密集型用多线程
计算密集型用多进程
Java多线程的情况下:
计算密集型操作:效率高
IO操作:效率高
5.Python线程编写
(1)多线程对于计算密集型无用
import time
import threading
v1=[11,22,33]
v2=[111,222,333]
def func(data,num):
time.sleep(2)
for i in range(len(data)):
data[i]=data[i]+num
t=threading.Thread(target=func,args=(v1,1))
t.start()
t1=threading.Thread(target=func,args=(v2,100))
t1.start()
time.sleep(6.1)
print(v1)#获得结果一共需要6秒左右
print(v2)
(2)多进程对于IO操作有用
import time
import threading
list=['思路.png','111.PNG','尚宏运.txt']
def task(arg):
with open(arg,mode='rb') as f:
time.sleep(5) #停顿一个五秒后全部都出来,而不是15秒
print(f.read())
for arg in list:
t=threading.Thread(target=task,args=(arg,))
t.start()
(3)线程编写具体用法
①线程的基本使用
import threading
def func(arg):
print(arg)
t=threading.Thread(target=func,args=(11,))
t.start() #123
print(123) #123
②主线程默认等子线程执行完毕
import time
import threading
def func(arg):
time.sleep(2)
print(arg)
t1=threading.Thread(target=func,args=(11,))
t1.start()
t2=threading.Thread(target=func,args=(11,))
t2.start()
print(123)
123 #先出来
11 #等两秒
11 #两个11一起出来
③让主线程不在等子线程执行完,主线程终止了所有子线程就都执行完 t2.setDaemon(True)
import time
import threading
def func(arg):
time.sleep(2)
print(arg)
t1=threading.Thread(target=func,args=(11,))
t1.setDaemon(True)
t1.start()
t2=threading.Thread(target=func,args=(11,))
t2.setDaemon(True)
t2.start()
print(123) #123
④开发者可以控制主线程等待子线程的最多等待时间
没有参数:让主程序在这里等着,等这个子程序执行完毕才可以继续往下走
import time
import threading
def func(arg):
time.sleep(2)
print(arg)
t1=threading.Thread(target=func,args=(11,))
t1.start()
t1.join()
t2=threading.Thread(target=func,args=(22,))
t2.start()
t2.join()
print(123)
有参数:让主程序在这里最多等n秒,无论是否执行完毕,都会继续往下走,但是如果此时走到了最后,
子程序还没执行完,程序不会停止,而是等子程序执行完再停止
import time
import threading
def func(arg):
time.sleep(arg)
print(arg)
t1=threading.Thread(target=func,args=(4,))
t1.start()
t1.join(1)
t2=threading.Thread(target=func,args=(5,))
t2.start()
t2.join(1)
print(123)
⑤线程名称
import threading
def func(arg):
t=threading.current_thread()
name=t.getName()
print(name,arg)
t1=threading.Thread(target=func,args=(11,))
t1.setName('我叫t1')
t1.start()
t2=threading.Thread(target=func,args=(12,))
a=t2.setName('我叫t2')
t2.start()
print(123)
⑥现成本质:t.start()并不是开始线程的意思,而是告诉CPU,我已经准备就绪,你可以调度我了
import threading
def func(arg):
print(arg)
t=threading.Thread(target=func,args=(11,))
t.start()
print(123)
⑦面向对象版本的多线程
一般写法
import threading
def func(arg):
print(arg)
t=threading.Thread(target=func,args=(11,))
t.start()# 实际上,就是执行threading模块中Thread类的run方法,run方法就是执行target=xxx中的xxx方法
还可以这样做
import threading
class MyThread(threading.Thread): #自己写一个类,直接继承Thread类,要执行run方法,首先从子类(自己写的类开始找),效果完全相同
def run(self):
print(11111,self._args,self._kwargs)
t1=MyThread(args=(11,))
t1.start()
t1=MyThread(args=(22,))
t1.start()
总结:
Ⅰ应用程序,进程,线程之间的关系
一个应用程序(软件),可以有多个进程(默认只有一个),一个进程中可以有多个线程(默认只有一个)
Ⅱ为什么要创建线程
线程是CPU工作的最小单元,在Java或C#中,创建线程可以利用多和优势实现并行操作
Ⅲ为什么要创建进程
进程与进程之间能够实现数据隔离(进程是为了提供环境让线程工作)
改变世界,改变自己!