多线程学习总结

Posted liuqianli

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程学习总结相关的知识,希望对你有一定的参考价值。

起线程

以函数的方式以一个线程

   

mport threading

import time  

def run(n):

print("task ",n )

time.sleep(2)

print("task done",n)  

start_time = time.time()

t_objs = [] #存线程实例

for i in range(10):

t = threading.Thread(target=run,args=("t-%s" %i ,)) #起线程

t.start()

t_objs.append(t) #为了不阻塞后面线程的启动,不在这里join,先放到一个列表里

   

for t in t_objs: #循环线程实例列表,等待所有线程执行完毕

t.join()

 

print("----------all threads has finished...")

print("cost:",time.time() - start_time)

   

测试时间略大于2秒. 主线程和这个主线程所启动的子线程是并行的,主线程的执行和子线程无关,要想在程序中让主线程等待子线程 的执行,只能加join() 方法.

   

以类的方式以线程

import threading

import time

   

class MyThread(threading.Thread):

def __init__(self,n,sleep_time):

super(MyThread,self).__init__()

self.n = n

self.sleep_time = sleep_time

def run(self):

# 重写父类的run 函数,所以只能是这个函数名

print("runnint task ",self.n )

time.sleep(self.sleep_time)

print("task done,",self.n )

   

t1 = MyThread("t1",2)

t2 = MyThread("t2",4)

   

t1.start()

t2.start()

   

t1.join()

t2.join()

# 写上这两句之后,先把t1t2执行完之后再执行print("main thread...."),不然就是先执行print("main thread....")

   

守护线程

import threading

import time

   

def run(n):

print("task ",n )

time.sleep(5)

print("task done",n,threading.current_thread())

   

start_time = time.time()

t_objs = [] #存线程实例

for i in range(5):

t = threading.Thread(target=run,args=("t-%s" %i ,))

# t.setDaemon(True) #把当前线程设置为守护线程

t.start()

t_objs.append(t) #为了不阻塞后面线程的启动,不在这里join,先放到一个列表里

   

# for t in t_objs: #循环线程实例列表,等待所有线程执行完毕,只有当这里面的线程执行完之后程序才往下走,

# t.join()

   

time.sleep(1)

print("----------all threads has finished...",threading.current_thread(),threading.active_count())

print("cost:",time.time() - start_time)

   

如果没有设置守护线程,

技术分享图片

可以看出,是先把print 语句执行完之后,程序再等待执行所有子线程执行完的,

   

加上守护线程之后的结果

技术分享图片

程序没有等待子线程执行完之后就退出了.

   

把join() 加上之后(也就是把那两行代码的注释取消之后)的结果:

技术分享图片

主要是比较他们执行的顺序.

   

线程锁

import threading

import time

   

def run(n):

lock.acquire() # 加锁,

global num

num += 1

time.sleep(0.2)

lock.release() # 解锁

   

lock = threading.Lock() # 生成一个线程锁实例

num = 0

t_objs = [] # 存线程实例

for i in range(5):

t = threading.Thread(target=run, args=("t-%s" % i,))

t.start()

t_objs.append(t) # 为了不阻塞后面线程的启动,不在这里join,先放到一个列表里

   

for t in t_objs: # 循环线程实例列表,等待所有线程执行完毕

t.join()

   

print("all threads has finished ", threading.current_thread(), threading.active_count())

   

print("num:", num)

   

加锁之后,在锁中间部分程序就是串行了,Python3中解释器自动加锁了,所以可以不再加锁,

递归锁

import threading, time

   

def run1():

print("grab the first part data")

lock.acquire()

global num

num += 1

lock.release()

return num

   

def run2():

print("grab the second part data")

lock.acquire()

global num2

num2 += 1

lock.release()

return num2

   

def run3():

lock.acquire()

res = run1() #这里执行run1,而run1中已有锁,所以需要递归锁,使用和平常锁一样,只是在声明时声明为递归锁就行

print(‘--------between run1 and run2-----‘)

res2 = run2()

lock.release()

print(res, res2)

   

num, num2 = 0, 0

lock = threading.RLock() #声明为递归锁

for i in range(1):

t = threading.Thread(target=run3)

t.start()

   

while threading.active_count() != 1:

print(threading.active_count())

else:

print(‘----all threads done---‘)

print(num, num2)

   

递归锁和线程锁用法是一样的,只是需要在声明时声明成递归锁就行

信号量

import threading, time

   

def run(n):

semaphore.acquire()

time.sleep(1)

print("run the thread: %s\\n" % n)

semaphore.release()

   

if __name__ == ‘__main__‘:

semaphore = threading.BoundedSemaphore(5) # 最多允许5个线程同时运行

for i in range(22):

t = threading.Thread(target=run, args=(i,))

t.start()

while threading.active_count() != 1:

pass # print threading.active_count()

else:

print(‘----all threads done---‘)

# print(num)

 

# 信息号和线程锁用法一样,只是在声明时声明一个信号量就行

 

事件Event

import time

import threading

   

event = threading.Event()

   

def lighter():

count = 0

event.set() #先设置绿灯

while True:

if count >5 and count < 10: #改成红灯

event.clear() #把标志位清了

print("\\033[41;1mred light is on....\\033[0m")

elif count >10:

event.set() #变绿灯

count = 0

else:

print("\\033[42;1mgreen light is on....\\033[0m")

time.sleep(1)

count +=1

   

def car(name):

while True:

if event.is_set(): #代表绿灯

print("[%s] running..."% name )

time.sleep(1)

else:

print("[%s] sees red light , waiting...." %name)

event.wait()

print("\\033[34;1m[%s] green light is on, start going...\\033[0m" %name)

   

light = threading.Thread(target=lighter,)

light.start()

   

car1 = threading.Thread(target=car,args=("Tesla",))

car1.start()

   

事件程序只有三种状态,set(), wait(),clear(),可以在这三种状态下分别做事情,

线程队列

# 生产者消费者模型

import threading,time

   

import queue

   

q = queue.Queue(maxsize=10) # 定义一个共用的线程queue

   

def Producer(name):

count = 1

while True:

q.put("包子%s" % count)

print("生产了包子",count)

count +=1

time.sleep(0.5)

   

def Consumer(name):

#while q.qsize()>0:

while True:

print("[%s] 取到[%s] 并且吃了它..." %(name, q.get()))

time.sleep(1)

   

p = threading.Thread(target=Producer,args=("zhangsan",))

c = threading.Thread(target=Consumer,args=("lishi",))

c1 = threading.Thread(target=Consumer,args=("wangwu",))

   

p.start()

c.start()

c1.start() 

 

 

以上是关于多线程学习总结的主要内容,如果未能解决你的问题,请参考以下文章

Java多线程学习(吐血超详细总结)

Java多线程学习(吐血超详细总结)

Java多线程学习(总结很详细!!!)

[转]Java多线程学习(总结很详细!!!)

多线程学习总结之 线程池

JAVA 学习总结 多线程