1.进程与线程的基本概念
进程:程序在数据集合上的一次运行,是操作系统进行资源分配的基本单位
线程:在实现了线程的操作系统中,线程是进行调度的最小单位
Linux有父进程和子进程,而Windows的进程是平等关系
一个标准的线程由线程ID、程序计数器PC、寄存器集合和堆栈组成
在许多系统中,创建一个线程比创建一个进程块10~100倍
每个进程认为自己独占整个操作系统的资源,每个进程根本不关心是否还有其他进程存在
进程像是一个容器,包含了程序本次运行所需要的所有资源,包括线程
同一个进程内的线程共享进程内的资源,每个线程拥有自己独立的栈,真正在线程中跑的是函数
2.Linux下进程的状态
3.python的线程和进程
当我们python3 hello.py时,会启动一个解释器进程,线程共享解释器进程
python中线程开发使用标准库threading
(1)线程启动
签名中=None代表接受任意类型,=()表示接受元组
import threading
def worker():
print("I'm working!")
print("finished")
#创建线程对象
t=threading.Thread(target=worker,name="worker")
#线程启动
t.start()
通过threading.Thread()创建一个线程对象,target是目标函数,name可以指定名称,
但是线程没有启动,通过调用t.start()才能将线程启动
import threading
def worker():
while True:
print("I'm working!")
print("finished")
#创建线程对象
t=threading.Thread(target=worker,name="worker")
#线程启动
t.start()
上述代码会一直执行线程t中的死循环,不会执行print("finished")语句
(2)线程退出
python中没有提供让线程取消的函数,要让线程取消的两种方法:
1.在线程内抛异常
2.让线程中的函数执行完
示例:
import threading
import time
def worker():
count=0
while True:
if(count>5)
#下述3条语句都可以退出线程
#raise RunTimeError(count)
#return
break
time.sleep(1)
print("I'm working")
count+=1
#创建线程对象
t=threading.Thread(target=worker,name="worker")
#线程启动
t.start()
print("End")
python中的线程没有优先级、没有线程组的概念,也不能被销毁、停止、挂起,那也就没有恢复和中断了
所有线程能从CPU中得到的时间片几乎相当
(3)线程的传参
import threading
def add(x,y):
ret=x+y
print(ret)
return ret
#创建线程对象
#三种传参方式
t=threading.Thread(target=add,args=(4,5))
t1=threading.Thread(target=add,args=(4,),kwargs={'y':6})
t2=threading.Thread(target=add,kwargs={'x':5,'y':6})
#线程启动
t.start()
t1.start()
t2.start()
print("End")
可以发现上述三个线程执行互不影响,因为每个线程在执行时,都有自己独立的栈,每个线程的本地变量随函数一起压栈,而全局变量不会压入栈中
线程传参和函数传参没什么区别,本质上就是函数传参
(4)threading的属性和方法
(5)Thread实例(线程对象)的属性
import threading
import time
#add函数
def add(x,y):
ret=x+y
print(ret)
getThreadInfo()
return ret
#打印当前线程和主线程的信息
def getThreadInfo():
print(threading.current_thread(),threading.main_thread())
ts=[]
#创建线程对象并存到列表中
t=threading.Thread(target=add,args=(4,5),name="t")
ts.append(t)
t1=threading.Thread(target=add,args=(4,),kwargs={'y':6},name="t1")
ts.append(t1)
t2=threading.Thread(target=add,kwargs={'x':5,'y':6},name="t2")
ts.append(t2)
if __name__== '__main__':
print("-------------------")
getThreadInfo()
time.sleep(2)
ts[0].start()
time.sleep(10)
print("******************")
if ts[0].is_alive():
print("alive")
else:
print("dead")
print(ts[0])
ts[0].start()
从上述结果可以看出,线程只能被启动一次,即只能调用一次start()
python的线程只有三种状态:未启动(未调用start)、启动(调用了start)、停止(线程执行结束)
停止之后不能再次启动,只能重新创建线程对象,再次启动该对象
start()是启动了新的线程,再调用了函数
import threading
def add(x,y):
ret=x+y
print(ret)
getThreadInfo()
return ret
def getThreadInfo():
print(threading.current_thread(),threading.main_thread())
#创建线程对象
t=threading.Thread(target=add,args=(4,5),name="t")
if __name__== '__main__':
t.start()
print("-------------------")
run是在主线程中执行了函数调用
import threading
def add(x,y):
ret=x+y
print(ret)
getThreadInfo()
return ret
def getThreadInfo():
print(threading.current_thread(),threading.main_thread())
#创建线程对象
t=threading.Thread(target=add,args=(4,5),name="t")
if __name__== '__main__':
t.run()
print("-------------------")
结论:因此使用start()方法才能启动多个线程