多线程
多线程
在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程
线程顾名思义,就是一条流水线工作的过程(流水线的工作需要电源,电源就相当于cpu),而一条流水线必须属于一个车间,一个车间的工作过程是一个进程,车间负责把资源整合到一起,是一个资源单位,而一个车间内至少有一条流水线。
所以,进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程才是cpu上的执行单位。
多线程(即多个控制线程)的概念是,在一个进程中存在多个线程,多个线程共享该进程的地址空间,相当于一个车间内有多条流水线,都共用一个车间的资源。例如,北京地铁与上海地铁是不同的进程,而北京地铁里的13号线是一个线程,北京地铁所有的线路共享北京地铁所有的资源,比如所有的乘客可以被所有线路拉。
开启线程的两种方式
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
#方法一:
# from threading import Thread
# import time
# def task(name):
# print('%s is runing'%name)
# time.sleep(3)
# print('%s is done'%name)
#
# if __name__ == '__main__':
# t = Thread(target=task,kwargs={'name':'线程'}) # 方法调用2
# t1 = Thread(target=task,kwargs={'name':'线程1'}) # 方法调用2
# t.start()
# t1.start()
# print('A')
# 方法二:
from threading import Thread
import time
class My_process(Thread): # 继承Process类
def __init__(self,name):
super().__init__() # 继承init方法
self.name = name
def run(self): # 固定写法
print('%s is runing'%self.name)
time.sleep(3)
print('%s id done'%self.name)
if __name__ == '__main__':
t = My_process('线程')
t.start()
print('b')
线程与进程的区别
- 同一个进程内的多个线程共享该进程内的地址资源
- 创建线程的开销要远小于创建进程的开销(创建一个进程,就是创建一个车间,涉及到申请空间,而且在该空间内建至少一条流水线,但创建线程,就只是在一个车间内造一条流水线,无需申请空间,所以创建开销小)
开进程的开销远大于开线程
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# 线程的开启速度比进程要快
from threading import Thread
from multiprocessing import Process
import time
def work(name):
print('%s is running'%name)
time.sleep(2)
print('%s is done'%name)
if __name__ == '__main__':
t = Thread(target=work,args=('ab',))
t.start()
print('线程')
p = Process(target=work,args=('abc',))
p.start()
print('主进程')
'''
ab is running
线程
主进程
abc is running
ab is done
abc is done
'''
同一进程内的多个线程共享该进程的地址空间
from threading import Thread
from multiprocessing import Process
import time
n = 100
def num():
global n
n = 0
if __name__ == '__main__':
t = Thread(target=num)
t.start()
t.join()
print('线程',n) # 同一进程内开启的多个线程是共享该进程地址空间的
# p = Process(target=num)
# p.start()
# p.join()
# print('进程',n) # 进程之间,地址空间是隔离的
'''
线程 0
进程 100
'''
瞅一眼PID
from threading import Thread
from multiprocessing import Process
from multiprocessing import current_process
import os
#开多个进程,每个进程都有不同的pid
# def task():
# print('子进程的PID:%s,主进程PID:%s'%(os.getpid(),os.getppid()))
#
# if __name__ == '__main__':
# p = Process(target=task)
# p.start()
# print('主进程的PID:%s'%os.getpid())
'''
主进程的PID:32228
子进程的PID:18680,主进程PID:32228
'''
#在主进程下开启多个线程,每个线程都跟主进程的pid一样
def task1():
print('主线程的PID:%s'%os.getpid())
if __name__ == '__main__':
t = Thread(target=task1,)
t.start()
print('主线程的pid:%s'%os.getpid())
'''
主线程的PID:24260
主线程的pid:24260
'''
Thread对象的其它属性方法
介绍
Thread实例对象的方法
# isAlive(): 返回线程是否活动的。
# getName(): 返回线程名。
# setName(): 设置线程名。
threading模块提供的一些方法:
# threading.currentThread(): 返回当前的线程变量。
# threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
# threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
例子:
from threading import Thread
import threading
import time
def work():
time.sleep(3) print(threading.current_thread().name)
if __name__ == '__main__':
t = Thread(target=work)
t.start()
print(threading.current_thread().getName())
print(threading.current_thread())# 主线程
print(threading.enumerate()) # 连同主线程有两个正
print(threading.active_count()) # 返回线程的数量
print('主线程')
'''
MainThread
<_MainThread(MainThread, started 29804)>
[<_MainThread(MainThread, started 29804)>, <Thread(Thread-1, started 23704)>]
2
主线程
Thread-1
'''
主线程等待子线程结束
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
from threading import Thread
import threading
import time
def work():
time.sleep(3)
print(threading.current_thread().name)
if __name__ == '__main__':
t = Thread(target=work,name='test')
t.start()
t.join()
print(t.is_alive())
print('主线程')
'''
test
False
主线程
'''