python之线程
一、什么是线程
-
进程:资源单位
-
线程:执行单位
-
进程:资源单位(起一个进程仅仅只是在内存空间中开辟一块独立的空间)
-
线程:执行单位(真正被cpu执行的其实是进程里面的线程,线程指的就是代码的执行过程,执行代码中所需要使用到的资源都找所在的进程索要)
进程和线程都是虚拟单位,只是为了我们更加方便的描述问题
二、为什么要有线程
- 开设进程
1.申请内存空间 耗资源
2.“拷贝代码” 耗资源 - 开线程
一个进程内可以开设多个线程,在用一个进程内开设多个线程无需再次申请内存空间操作 - 总结:
开设线程的开销要远远的小于进程的开销
同一个进程下的多个线程数据是共享的!!!
三、怎么开启线程
- 开进程和开线程的步骤基本都是一样的 只是导入的模块不一样而已
- 开进程代码必须写在main下面而开线程则无需这么做
3.1、方式一
from threading import Thread
import time
def task(name):
print(F'{name} is running')
time.sleep(1)
print(F'{name} is stopping')
# 开线程的代码不需要写在main中
# 但是习惯性的将启动命令写在main下面
t = Thread(target=task,args=('tzh',))
t.start()
print('我是主线程')
3.2、方式二
from threading import Thread
import time
class MyThead(Thread):
def __init__(self,name):
#重写别人的方法
super().__init__()
self.name = name
def run(self):
print(F'{self.name} is running')
time.sleep(1)
print(F'{self.name} is stoppings')
print('tzh666')
if __name__ == '__main__':
t = MyThead('tzh')
t.start()
四、线程对象的join方法
from threading import Thread
import time
def task(name):
print('%s is running'%name)
time.sleep(3)
print('%s is over'%name)
if __name__ == '__main__':
t = Thread(target=task,args=('egon',))
t.start()
t.join() # 主线程等待子线程运行结束再执行
print('主')
五、同一个进程下的多个线程数据是共享的
from threading import Thread
import time
money = 100
def task():
global money
money = 666
print(money)
if __name__ == '__main__':
t = Thread(target=task)
t.start()
t.join()
print(money)
六、线程对象属性及其他方法
from threading import Thread, active_count, current_thread
import os, time
def task():
print(F'子进程号是:{os.getpid()}')
print(F'子线程名字是:{current_thread().name}')
time.sleep(2)
if __name__ == '__main__':
t = Thread(target=task)
t.start()
#打印出来是一样的,因为他们在同一个下进程中
print(F'主进程号是:{os.getpid()}')
print(F'主线程名字是:{current_thread().name}')
print(F'活跃的线程数:{active_count()}')
七、守护线程
- 主线程运行结束之后不会立刻结束 会等待所有其他非守护线程结束才会结束
- 因为主线程的结束意味着所在的进程的结束
from threading import Thread
import time
def task(name):
print('%s is running'%name)
time.sleep(1)
print('%s is over'%name)
if __name__ == '__main__':
t = Thread(target=task, args=('tzh', ))
t.daemon = True
t.start()
print('主')
from threading import Thread
import time
def foo():
print(123)
time.sleep(1)
print('end123')
def func():
print(456)
time.sleep(3)
print('end456')
if __name__ == '__main__':
t1 = Thread(target=foo)
t2 = Thread(target=func)
t1.daemon = True
t1.start()
t2.start()
print('主.......')
--输出--
123
456
主.......
end123
end456
八、线程互斥锁
from threading import Thread, Lock
import time
money = 100
mutex = Lock()
def task():
global money
#上锁
mutex.acquire()
tmp = money
time.sleep(0.1)
money = tmp - 1
#用完之后释放
mutex.release()
if __name__ == '__main__':
t_list = []
for i in range(100):
t = Thread(target=task)
t.start()
t_list.append(t)
for t in t_list:
t.join()
print(money)