1、关于线程
1)什么是线程
把操作系统比喻成工厂
进程:资源单位(工厂里面的车间)
线程:执行单位(车间里面的流水线)
注意:每一个进程中都会自带一个"主"线程,进程中的线程数据是共享的
2)为什么要有线程
开一个进程:
申请内存空间 耗时
将代码拷贝到申请的内存空间中 耗时
开线程:
不需要申请内存空间
开线程的开销远远小于开进程的开销!!!
3)如何使用线程....
2、开启线程的两种方式
方式一:通过制定target
from threading import Thread
import time
import random
def task(name):
print('%s is running ' % name)
time.sleep(random.random())
print('%s is over' % name)
if __name__ == '__main__':
t = Thread(target=task, args=('Tom',))
t.start() # 开启线程的速度非常快,几乎代码执行完线程就已经开启
print('主')
>>>:
Tom is running
主
Tom is over
方式二:通过继承类的方式
from threading import Thread
import time
import random
class MyThread(Thread):
def __init__(self, name):
super().__init__()
self.name = name
def run(self):
print('%s is running' % self.name)
time.sleep(random.random())
print('%s is end' % self.name)
if __name__ == '__main__':
p = MyThread('json')
p.start()
print('主')
>>>:
json is running
主
json is end
3、线程之间的数据共享
from threading import Thread
x = 100
def task():
global x
x = 666
t = Thread(target=task)
t.start()
t.join()
print(x)
>>>:
666
4、线程互斥锁
线程之间数据共享:
多个线程操作同一份数据???出现数据不安全的情况
涉及到多个线程或进程操作同一份数据的时候,通常都需要将并行并发变成串行
虽然牺牲了效率但是提高了数据的安全性
针对不同的数据,需要加不同的锁
锁(独立卫生间)
from threading import Thread, Lock
import time
import random
mutex = Lock()
n = 100
def task():
global n
mutex.acquire()
tmp = n
time.sleep(random.random())
n = tmp - 1
mutex.release()
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(n) # 0
5、线程对象的其他属性和方法
获取线程id:os.getpid()
获取线程名:current_thread().name current_thread().getName()
当前活跃的线程数:active_count()
from threading import Thread, active_count, current_thread
import os
import time
def task(name):
print('%s is running'%name,os.getpid())
print('%s is running' % name, current_thread().name
time.sleep(1)
print('%s is over' % name)
def info(name):
print('%s is running' % name, current_thread().name
time.sleep(1)
print('%s is over' % name)
t = Thread(target=task, args=('Tom',))
t1 = Thread(target=info, args=('Bob',))
t.start()
t1.start()
t.join()
print(active_count()) # 当前存活的线程数
print(os.getpid())
print(current_thread().name)>>>:
Tom is running 18220
Tom is running Thread-1
Bob is running Thread-2
Bob is over
Tom is over
1
18220
MainThread
6、守护线程
主线程必须等待所有非守护线程的结束才能结束
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=('Tom',))
t.daemon = True
t.start()
print('主')
>>>:
Tom is running
主
7、线程join
主线程等待子线程运行完毕