一、线程理论
1、什么是线程
线程指的是一条流水线的工作过程
进程根本就不是一个执行单位,进程其实是一个资源单位--------将资源集合到一起:
一个进程内自带一个线程,线程才是CPU上的执行单位
2、进程VS线程
1、同一进程内的线程们共享该进程内资源,不同进程内的线程资源肯定是隔离的
2、创建线程的开销比创建进程要小的多(大概是100倍)
把操作系统比做一座工厂进行比对:
工厂=====》车间=====》流水线
操作系统====》进程=====》线程
开启一个进程,就是申请了一个内存空间,将产生的数据丢掉里面,而代码的运行就是线程
多个进程内存空间彼此是隔离的,而同一个进程下的多个线程,共享该进程内的数据,分散于不同进程之间的线程数据是隔离的
3、创建进程的开销远大于开启线程的开销:
造进程要向操作系统发请求,由操作系统帮你申请一个内存空间,
在一个进程再开启一个请求,不需要在申请内存空间,只需要告诉操作系统只需要执行代码即可
创建进程的开销要远大于线程
形象比喻:
如果我们的软件是一个工厂,该工厂有多条流水线,流水线工作需要电源,电源只有一个即cpu(单核cpu)
一个车间就是一个进程,一个车间至少一条流水线(一个进程至少一个线程)
创建一个进程,就是创建一个车间(申请空间,在该空间内建至少一条流水线)
而建线程,就只是在一个车间内造一条流水线,无需申请空间,所以创建开销小
进程之间是竞争关系,线程之间是协作关系
形象比喻:
车间直接是竞争/抢电源的关系,竞争(不同的进程直接是竞争关系,是不同的程序员写的程序运行的,迅雷抢占其他进程的网速,360把其他进程当做病毒干死)
一个车间的不同流水线式协同工作的关系(同一个进程的线程之间是合作关系,是同一个程序写的程序内开启动,迅雷内的线程是合作关系,不会自己干自己)
二、开启线程的两种方式
方式一、
直接调用线程类,指定开启的子进程函数
#开启线程的方式一、 # 常用方式: from multiprocessing import Process from threading import Thread import time def task(name): print('%s is running' %name) #最先被打印出来 time.sleep(3) print('%s is done' % name) #最后被打印出来 if __name__ == '__main__': #线程可以不用__main__,但是开启进程必须用,因为开启进程为从新在导入模块 # t=Thread(target=task,args=('egon',)) t=Process(target=task,args=('egon',)) t.start() #开启线程的速速很快,几乎向操作系统发起请求就被开启(不需要申请内存空间);而开启进程要向操作系统发起请求,申请内存空间,而这个时间已经够运行到下一行代码的了 print('主线程') #开启线程打印结果: ''' egon is running 主线程 egon is done ''' #开启进程打印结果: ''' 主线程 egon is running egon is done '''
方式二、
自定义一个线程类,并继承Thread类,然后调用自定义类
#自定义一个类、但是还要用被人内置的方法名 from multiprocessing import Process from threading import Thread import time class MyThread(Thread): def run(self): print('%s is running' %self.name) time.sleep(3) if __name__ == '__main__': t=MyThread() t.start() print('主线程')
三、进程与线程对比
#2、线程创建开销小-----因为其不需要申请内存空间 # 线程的开启速度更快 from threading import Thread from multiprocessing import Process import os def work(): print('hello') if __name__ == '__main__': #在主进程下开启线程 t=Thread(target=work) t.start() print('主线程/主进程') ''' 打印结果: hello #子进程内的打印先被打印出来,因为子进程开启不需要申请内存空间,所以开启速度非常快 主线程/主进程 ''' #在主进程下开启子进程 t=Process(target=work) t.start() print('主线程/主进程') ''' 打印结果: 主线程/主进程 #由于子进程的开启需要申请内存空间,需要时间,而代码的运行速度是很快的,所以'主线程/主进程' 会先与子进程的代码被打印出来 hello '''