線程的創(chuàng)建
1.通過創(chuàng)建Thread類指定target來實現
from threading import Thread
import time
def test():
print("----------1-------")
time.sleep(1)
for i in range(5):
t = Thread(target=test)
t.start()
2.通過繼承Thread類重寫run方法來實現
from threading import Thread
import time
def test():
print("----------1-------")
time.sleep(1)
class MyThread(Thread):
def run(self):
test()
for i in range(5):
t = MyThread()
t.start()
3.同一個進程中的線程之間共享全局變量
線程與進程的區(qū)別
定義的不同
- 進程是系統(tǒng)進行資源分配和調度的一個獨立單位.
- 線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程自己基本上不擁有系統(tǒng)資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源.
互斥鎖
#創(chuàng)建鎖
mutex = threading.Lock()
#鎖定
mutex.acquire([blocking])
#釋放
mutex.release()
死鎖
避免死鎖的方式
1.上鎖添加超時時間
mutex = Lock()
mutex.acquire(timeout=3)
2.銀行家算法
生產者與消費者模式
#encoding=utf-8
import threading
import time
#python2中
from Queue import Queue
#python3中
# from queue import Queue
class Producer(threading.Thread):
def run(self):
global queue
count = 0
while True:
if queue.qsize() < 1000:
for i in range(100):
count = count +1
msg = '生成產品'+str(count)
queue.put(msg)
print(msg)
time.sleep(0.5)
class Consumer(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()
for i in range(500):
queue.put('初始產品'+str(i))
for i in range(2):
p = Producer()
p.start()
for i in range(5):
c = Consumer()
c.start()
隊列就是用來給生產者和消費者解耦的
ThreadLocal
import threading
# 創(chuàng)建全局ThreadLocal對象:
local_school = threading.local()
def process_student():
# 獲取當前線程關聯的student:
std = local_school.student
print('Hello, %s (in %s)' % (std, threading.current_thread().name))
def process_thread(name):
# 綁定ThreadLocal的student:
local_school.student = name
process_student()
t1 = threading.Thread(target=process_thread, args=('dongGe',), name='Thread-A')
t2 = threading.Thread(target=process_thread, args=('老王',), name='Thread-B')
t1.start()
t2.start()
t1.join()
t2.join()
異步
from multiprocessing import Pool
import time
import os
def test():
print("---進程池中的進程---pid=%d,ppid=%d--" % (os.getpid(), os.getppid()))
for i in range(3):
print("----%d---" % i)
time.sleep(1)
return "hahah"
def test2(args):
print("---callback func--pid=%d" % os.getpid())
print("---callback func--args=%s" % args)
pool = Pool(3)
pool.apply_async(func=test, callback=test2)
time.sleep(5)
print("----主進程-pid=%d----" % os.getpid())
GIL 全局解釋器鎖
python解釋器在解釋python程序時桨菜,多線程的任務會存在GIL問題,也就是多線程執(zhí)行時實際是只有單線程會占用CPU,多核CPU并不會同時執(zhí)行多線程的程序寒砖。
避免GIL問題的方式:
1.采用多進程來實現多任務
2.采用C語言來實現多線程任務
把一個c語言文件編譯成一個動態(tài)庫的命令(linux平臺下):
gcc xxx.c -shared -o libxxxx.so
from ctypes import *
from threading import Thread
#加載動態(tài)庫
lib = cdll.LoadLibrary("./libdeadloop.so")
#創(chuàng)建一個子線程忍捡,讓其執(zhí)行c語言編寫的函數譬涡,此函數是一個死循環(huán)
t = Thread(target=lib.DeadLoop)
t.start()
#主線程合蔽,也調用c語言編寫的那個死循環(huán)函數
#lib.DeadLoop()
while True:
pass