线程和进程一样是抽象出来的,做个比喻,进程好比一个造车的车间,而线程就是里面的流水线,有造车轱辘的,还有车架的等等
进程属于一个资源单位,而线程是cup上的执行单位
多线程的概念:
是一个进程中的多个线程,注意是一个进程,多个线程享有一个进程的地址空间,共享进程内的资源。
线程的创建开销小:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from threading import Thread import os import time def work(): print('%s is working'%os.getpid()) time.sleep(2) print('%s is ending'%os.getpid()) if __name__ == '__main__': t = Thread(target=work,) t.start() print('主 %s' % os.getpid()) 运行结果: 7604 is working 主 7604 7604 is ending
创建开销小
从结果中可以看出 线程的pid和进程的pid是一样的***
线程与进程的区别
1 开在一个进程里的多线程的内存空间是一样的,都是主进程的内存空间,而开辟一个新 的进程则是重新开辟一个空间地址。
2 多线程可以共享一个进程内的资源,而进程之间的资源是隔离的。
3 新的线程开销小,至于要在原来的进程基础上开辟一条线程;进程的开销大,需要开辟一个新的空间。
开启线程的两种方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from threading import Thread import os def work(): print('%s is working' % os.getpid()) if __name__ == '__main__': t = Thread(target=work,) t.start() print('主 %s' % os.getpid())
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from threading import Thread import os class Work(Thread): def __init__(self,name): super(Work, self).__init__() self.name = name def run(self): print('%s is running %s'%(os.getpid(),self.name)) if __name__ == '__main__': t = Work('haidong') t.start() print('主 %s' % os.getpid())
线程中主要的方法:守护线程,jion
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from threading import Thread import os import time def work(): print('%s is working' % os.getpid()) time.sleep(2) print('%s is ending' % os.getpid()) if __name__ == '__main__': t = Thread(target=work,) # t.daemon = True t.start() print('主 %s' % os.getpid())
*****守护线程什么时候被回收呢? 主线程运行完了,进程就会结束,所以主线程要等到所有的非守护线程都运行完了才结束,这时回收守护线程。
******守护进程什么时候被回收呢? ok! 在主进程的代码执行完了, 守护进程就会被回收!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from threading import Thread import os import time def work(): print('%s is working' % os.getpid()) time.sleep(2) print('%s is ending' % os.getpid()) if __name__ == '__main__': t = Thread(target=work,) t.start() t.join() # 主线程会等到子线程运行完在运行 print('主 %s' % os.getpid())
线程中不常有的方法:
Thread实例对象的方法 # isAlive(): 返回线程是否活动的。 # getName(): 返回线程名。 # setName(): 设置线程名。 threading模块提供的一些方法: # threading.currentThread(): 返回当前的线程变量。 # threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。 # threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
线程练习:
基于线程的套接字练习:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import socket from threading import Thread phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 参数:网络网络协议, SOCK_STREAM tcp协议 phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) phone.bind(('127.0.0.1', 8081)) phone.listen(5) # 参数, 能挂起几个链接数 def talk(conn): while 1: # 通信循环 try: ret = conn.recv(1024) if not ret: break # 对于linux 系统的异常处理 conn.send(ret.upper()) except Exception: break conn.close() if __name__ == '__main__': while 1: # 链接循环 conn, client_addr = phone.accept() # 元祖,conn 代表链接, client_addr接收到一个IP地址和接口 print(client_addr) p = Thread(target=talk,args=(conn,)) p.start() phone.close()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import socket phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) phone.connect(('127.0.0.1', 8081)) while 1: cmd = input('>>: ').strip() if not cmd: continue phone.send(cmd.encode('utf_8')) ret = phone.recv(1024) print(ret.decode('utf-8')) phone.close()
模拟文本编辑器:简单的三种要求,写,改,存
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from threading import Thread import json l = [] l1 =[] def xie(): while 1: value = input('>>>: ') if not value: continue l.append(value) def geshihua(): while 1: if l: value = l.pop() l1.append(value.upper()) def baocun(): while 1: if l1: with open('db.txt', 'a') as f: value = l1.pop() f.write('%s ' % value) f.flush() if __name__ == '__main__': t1 = Thread(target=xie) t2 = Thread(target=geshihua) t3 = Thread(target=baocun) t1.start() t2.start() t3.start()
全局解释器锁:这是个什么东西呢?英文:Global Interpreter Lock 简写:GIL
他是用来干什么的呢?由于python的内存机制,还有为了保护cpython内的数据安全,还有对于多线程对于cpython的竞争变得有序化,给cpython加的一把锁。
当我们要执行python内的代码,修改变量时,就要向cPython请求权限,当多个代码都要进行时,锁的作用就起到了,自己用脚后跟想也能想明白把,要是都去执行cPython内的执行代码,肯定会乱对吧!!