线程和进程
- 线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位
- 一个进程由一个或多个线程组成,线程是一个进程中代码的不同执行路线
- 进程之间相互独立,但同一线程下的各个线程之间共享程序的内存空间(包括代码段,数据集,堆等)及一些进程级的资源(如打开文件和信号等),某进程内的线程在其他进程中不可见
- 线程上下文切换比进程上下文切换要快的多
创建多线程
方法1:
调用threading库的Thread类:
def test(x):
print(x)
time.sleep(2)
t1 = threading.Thread(target=test,args=(1,))
t2 = threading.Thread(target=test,args=(2,))
t1.start()
t2.start()
方法2:
以继承于Thread类的方式:
cLass MyThread(threading.Thread):
def__ init__ (seLf, n):
super (MyThread, seLf).__ init__()
self.n = n
def run(self):
print('以类的方式创建多线程',self.n)
time.sleep(3)
r1 = MyThread(1)
r2 = MyThread(2)
r1.start()
r2.start()
一些常用方法
查看活动的线程数:threading.active_count() 查看当前线程:threading.current_thread()
守护线程
使用setDaemon(True)把所有的子线程都变成了主线程的守护线程, 因此当主线程结束后,子线程也会随之结束,所以当主线程结束后,整个程序就退出了。 所谓’线程守护’,就是主线程不管该线程的执行情况,只要是其他子线程结束且主线程执行完毕,主线程都会关闭。也就是说:主线程不等待该守护线程的执行完再去关闭
def run(n):
print('task',n)
time.sleep(2)
print('5s')
time.sleep(2)
print('3s')
time.sleep(2)
print('1s')
if __name__ == '__main__':
t=threading.Thread(target=run,args=('t1',))
t.setDaemon(True) #把子线程设置为守护线程,必须在start()之前设置
t.start()
t.join() #设置主线程等待子线程结束
print('end')
线程锁
由于线程之间是进行随机调度,并且每个线程可能只执行n条执行之后,当多个线程同时修改同一条数据时可能会出现脏数据,所以出现了线程锁,即同一时刻允许一个线程执行操作。 由于线程之间是进行随机调度的,如果有多个线程同时操作一个对象,如果没有很好地保护该对象,会造成程序结果的不可预期,我们因此也称为“线程不安全”。 为了防止上面情况的发生,就出现了线程锁(Lock)
def work():
global n
lock.acquire()
temp = n
time.sleep(0.1)
n = temp-1
lock.release()
if __name__ == '__main__':
lock = Lock()
n = 100
l = []
for i in range(100):
p = Thread(target=work)
l.append(p)
p.start()
for p in l:
p.join()
递归锁
递归锁:RLcok类的用法和Lock类一样,支持嵌套,在多个锁没有释放的时候一般会使用RLock类
def func(lock):
global gl_num
lock.acquire()
gl_num += 1
time.sleep(1)
print(gl_num)
lock.release()
if __name__ == '__main__':
gl_num = 0
lock = threading.RLock()
for i in range(10):
t = threading.Thread(target=func,args=(lock,))
t.start()
实例:
在一个线程中,每秒循环输出当前的年月日时分秒 于此同时,在另一个线程中,实现张三的姓名每2秒打印输出4次结束。 注意:都需要使用类和继承实现功能
import threading
import time
class MyThread1(threading.Thread):
def run(self):
while (True):
localetime = time.asctime(time.localtime(time.time()))
print(localetime)
time.sleep(1)
class MyThread2(threading.Thread):
def __init__(self,name):
super(MyThread2, self).__init__()
self.name=name
def run(self):
for i in range(4):
print(self.name)
time.sleep(2)
if __name__ == '__main__':
mt1 = MyThread1()
mt2 = MyThread2("张三")
mt2.start()
mt1.start()