线程
进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合)而线程才是cpu上的执行单位
1.同一个进程内的多个线程共享该进程内的地址资源
2.创建线程的开销远小于创建进程的开销(创建一个进程,就是创建一个车间,涉及到申请空间,而且在该空间内建至少一条流水线,但创建线程,就只是在一个车间 内造一条流水线,无需申请空间,所以创建开销小)
开启线程的两种方式
import time import random from threading import Thread def piao(name): print('%s piaoing' %name) time.sleep(random.randrange(1,5)) print('%s piao end' %name) if __name__ == '__main__': #实例化得到一个对象 t1=Thread(target=piao,args=('egon',)) #必须加,号 #调用对象下的方法,开启一个进程 t1.start() print('主线程') ''' 打印结果: egon piaoing 主线程 egon piao end '''
import time import random from threading import Thread class MyThread(Thread): def __init__(self,name): super().__init__() self.name=name def run(self): print('%s piaoing' %self.name) time.sleep(random.randrange(1,5)) print('%s piao end' %self.name) if __name__ == '__main__': t1=MyThread('egon') t1.start() #start会自动调用run print('主') ''' 打印结果: egon piaoing 主 egon piao end '''
进程线程的区别
1.开进程的开销远大于开线程
2.同一进程内的多个线程共享该进程的地址空间;而进程之间的内存是隔离的
3.开多个进程,每个进程都有不同的pid;在主进程下开启多个线程,每个线程的pid都和主进程的pid一样
# 1.开进程的开销远大于开线程 import time from threading import Thread from multiprocessing import Process def piao(name): print('%s piaoing' %name) time.sleep(1) print('%s piao end' %name) if __name__ == '__main__': p1 = Process(target=piao, args=('egon',)) # 必须加,号 p1.start() # t1=Thread(target=piao,args=('egon',)) #必须加,号 # t1.start() print('主线程') ''' 打印结果: 进程 主线程 egon piaoing egon piao end 线程 egon piaoing 主线程 egon piao end '''
from threading import Thread from multiprocessing import Process n=100 def task(): global n n=0 if __name__ == '__main__': # p1 = Process(target=task) # 必须加,号 # p1.start() # p1.join() t1=Thread(target=task,) #必须加,号 t1.start() t1.join() print('主线程',n) ''' 打印结果 进程 主线程 100 证明进程在使用内存空间是互相隔离 线程 主线程 0 证明同一进程内的多个线程共享该进程的地址空间 '''
from threading import Thread from multiprocessing import Process,current_process import os n=100 def task(): # print(current_process().pid) # 查看当前进程的id号 print('子进程PID:%s 父进程PID:%s' %(os.getpid(),os.getppid())) if __name__ == '__main__': p1 = Process(target=task) # 必须加,号 p1.start() # print('主线程',current_process().pid) print('主进程', os.getpid()) ''' 打印结果 主进程 10576 子进程PID:9744 父进程PID:10576 ''' def task(): print('子进程PID:%s' %(os.getpid())) if __name__ == '__main__': t1 = Thread(target=task()) print('主进程', os.getpid()) ''' 打印结果: 子进程PID:9956 主进程 9956 '''
Thread的其他属性
Thread对象的方法:
- t.isAlive() 和 t.is_alive() # 返回线程是否存活
- t.setName() # 设置进程名
- t.getName() # 返回进程名
threading模块的方法:
- threading.currentThread() # 获取当前线程的对象
- threading.enumerate() # 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
- threading.activeCount() # 返回已经启动的线程数量,与len(threading.enumerate())有相同的结果。
from threading import Thread,currentThread,active_count,enumerate import time def task(): print('%s is running' %currentThread().getName()) # currentThread()相当于对象t1 time.sleep(2) print('%s is done' % currentThread().getName()) if __name__ == '__main__': t=Thread(target=task,name='子线程1') t.start() t.setName('儿子线程1') # 修改线程的名 t.join() # 让主线程去等待子线程结束 print(t.getName()) currentThread().setName('主线程') # 设置主线程的名字 print(t.is_alive()) # 查看是否存活 print('主线程',currentThread().getName()) t.join() print(active_count()) # 活跃的线程数 print(enumerate()) # 拿到当前活跃线程的对象 ''' 打印结果: 子线程1 is running 儿子线程1 is done 儿子线程1 False 主线程 主线程 '''