- 程序:一堆代码以文本形式存入一个文档
- 进程:程序运行的一个状态(邻居对门的关系)
- 包含地址,空间,内存,数据栈等
- 每个进程有自己独立的运行环境,多进程共享数据是一个问题
- 线程:(在一个屋拼居的关系)
- 一个进程的独立运行片段,一个进程可以由多个线程组成
- 一个进程的多个线程间共享数据和上下文运行环境
- 互斥
- 全局解释器锁(GIL)
- python代码的执行是由python虚拟机进行控制
- 在主循环中只能有一个控制线程在运行
- 哪个变量需要线程共享资源多锁哪个锁并不是锁住谁而是一个令牌
--------------------------------------------Lock锁------------------------------------------------------------------
import threading sum = 0 loopsum = 100000 lock = threading.Lock() def MyAdd(): global sum , loopsum for i in range(1,loopsum): lock.acquire() sum += 1 lock.release() def MyMinu(): global sum , loopsum for i in range(1,loopsum): lock.acquire() sum -= 1 lock.release() if __name__=='__main__': print("{0}".format(sum)) t1 = threading.Thread(target=MyAdd) t2 = threading.Thread(target=MyMinu) t1.start() t2.start() t1.join() t2.join() print("{0}".format(sum))
------------------------------经过多长时间调用线程函数--threading.Timer-----------------------------------------------------
#经过多长时间调用线程函数 threading.Timer import threading import time def func(): print('开始') time.sleep(4) print('结束') if __name__=='__main__': t = threading.Timer(6,func) t.start() i = 0 while True: print('{}---------------'.format(i)) time.sleep(3) i+=1
-------------------------可重入锁 一个锁 可以被一个线程多次申请 主要解决递归申请的情况------------------------------------
#可重入锁 一个锁 可以被一个线程多次申请 主要解决递归申请锁的情况 import threading import time class MyThread(threading.Thread): def run(self): global num time.sleep(1) if mutex.acquire(1): num = num+1 msg = self.name +'set num to '+str(num) print(msg) mutex.acquire() mutex.release() mutex.release() num = 0 mutex = threading.RLock() def test1(): for i in range(5): t = MyThread() t.start() if __name__=='__main__': test1()
- thread:有问题 不好用 python3 改成了_thread
----------------------------------------------- threading:通行的包------------------------------------------------------------
import time import threading def lo1(): print('函数1开始{}'.format(time.ctime())) time.sleep(4) print('函数1结束{}'.format(time.ctime())) def lo2(): print('函数2开始{}'.format(time.ctime())) time.sleep(2) print('函数2结束{}'.format(time.ctime())) def min(): print('调用俩个函数开始时间{}'.format(time.ctime())) t = threading.Thread(target=lo1,)#有参数传args t.start() l = threading.Thread(target=lo2,) l.start() t.join() l.join() print('俩个函数结束时间{}'.format(time.ctime())) if __name__=='__main__': min()
- 守护线程
- 如果在程序中将子线程设置为守护线程则子线程会在主线程结束时自动退出
- 守护线程不重要或者不予许离开主线程
- 守护线程能否有效果跟环境有关
----------------------------------------------------- 非守护线程----------------------------------------------------------------
import time import threading def fun(): print('函数1开始{}'.format(time.ctime())) time.sleep(2) print('函数1结束{}'.format(time.ctime())) print('主线程开始') t = threading.Thread(target=fun) t.start() time.sleep(1) print('主线程结束')
-----------------------------------------------------守护线程-------------------------------------------------------------------
import time import threading def fun(): print('函数1开始{}'.format(time.ctime())) time.sleep(2) print('函数1结束{}'.format(time.ctime())) print('主线程开始') t = threading.Thread(target=fun) t.daemon=True t.start() time.sleep(1) print('主线程结束')
- 线程常用属性
- threding.currentThread() #返回当前线程变量
- threading.enumerate() #返回一个包含正在运行的线程数量,效果跟 len(threading.enumerate)
- thr.setName #给线程设置名字
- thr.getName #得到线程的名字
---------------------------------直接实例一个子类 (需要重新写run方法)--------------------------------------------------------
import threading import time class MyThread(threading.Thread): def __init__(self,arg): #注意可以不写一旦写必须调用父类的构造函数 super(MyThread,self).__init__() self.arg = arg def run(self): #注意一定要重写run方法 所有任务都是run函数执行 time.sleep(2) print("Go!!!{}".format(self.arg)) for i in range(5): t = MyThread(i) t.start() t.join() print('走完程序')
-----------------------------------------------企业里比较实用的写法------------------------------------------------------------
import threading import time loop = [4,2] class ThreadFunc: def __init__(self,name): self.name = name def loop(self,nloop,nsec): """ :param nloop: loop 函数的名称 :param nsec: 系统休眠的时间 :return: """ print('启动回路 ',nloop,'at',time.ctime()) time.sleep(nsec) print('完后循环 ',nloop,'at',time.ctime()) def main(): print('开始时间:',time.ctime()) t = ThreadFunc("loop") t1 = threading.Thread(target=t.loop,args=("LOOP1!",4)) t2 = threading.Thread(target=ThreadFunc('loop').loop,args=("LOOP2!",2)) t1.start() t2.start() t1.join() t2.join() print("程序走完",time.ctime()) if __name__=='__main__': main()
-----------------------------------------------互斥锁-----------------------------------------------------------------------
import threading sum = 0 loopsum = 100000 lock = threading.Lock() def MyAdd(): global sum , loopsum for i in range(1,loopsum): lock.acquire() #上锁 sum += 1 lock.release() #解锁 def MyMinu(): global sum , loopsum for i in range(1,loopsum): lock.acquire() #上锁 sum -= 1 lock.release() #解锁 if __name__=='__main__': print("{0}".format(sum)) t1 = threading.Thread(target=MyAdd) t2 = threading.Thread(target=MyMinu) t1.start() t2.start() t1.join() t2.join() print("{0}".format(sum))
---------------------------------------------------创建线程池--------------------------------------------------------------------
import time import threading import queue class Producer(threading.Thread): def fun(self): global queue count = 0 while True: if queue.qsize() < 1000: for i in range(100): count += 1 msg = "生成产品"+str(count) queue.put(msg) print(msg) time.sleep(0.5) class Counmer(threading.Thread): def run(self): global queue while True: if queue.qsize()>100: for i in range(3): msg = self.name +'消费了'+queue.get() print(msg) time.sleep(1) if __name__=="__main__": queue = queue.Queue() for i in range(500): queue.put("初始产品"+str(i)) for i in range(2): p = Producer() p.start() for i in range(5): c = Counmer() c.start()
-----------------------------------------------多长时间后调用线程--------------------------------------------------------------
#经过多长时间调用线程函数 threading.Timer import threading import time def func(): print('开始') time.sleep(4) print('结束') if __name__=='__main__': t = threading.Timer(6,func) t.start() i = 0 while True: print('{}---------------'.format(i)) time.sleep(3) i+=1
-----------------------------------------------重入锁----------------------------------------------------------------------------
#可重入锁 一个锁 可以被一个线程多次申请 主要解决递归申请锁的情况 import threading import time class MyThread(threading.Thread): def run(self): global num time.sleep(1) if mutex.acquire(1): num = num+1 msg = self.name +'set num to '+str(num) print(msg) mutex.acquire() mutex.release() mutex.release() num = 0 mutex = threading.RLock() def test1(): for i in range(5): t = MyThread() t.start() if __name__=='__main__': test1()