线程

Process 进程类   Thread  线程类   二者用法相同

1.效率对比

import time
import os
from multiprocessing import Process as Thread     #进程
def func():
    n = 1+ 2 +3
    n**2
if __name__ == '__main__':
    start = time.time()
    l = []
    for i in range(100):
        t = Thread(target=func)
        t.start()
        # print(t)            #<Process(Process-1, started)>
        l.append(t)
    for t in l:
        t.join()
    print(time.time()-start)



import time
import os
from threading import  Thread             #线程
def func():
    n = 1+ 2 +3
    n**2
if __name__ == '__main__':
    start = time.time()
    l = []
    for i in range(100):
        t = Thread(target=func)
        t.start()
        # print(t)
        l.append(t)
    for t in l:
        t.join()
    print(time.time()-start)

3.661578893661499
0.02001357078552246

Process finished with exit code 0

2.线程的数据共享

import time
from threading import Thread
n = 100
def func():
    global n
    # time.sleep(1)
    n -= 1
if __name__ == '__main__':
    t = Thread(target=func)
    print(n)
    t.start()                  
    print(n)

100
99

Process finished with exit code 0

3. 开启线程的另一种方式   (进程同理)

from threading import Thread
class Mythread(Thread):
    def __init__(self,args):
        super().__init__()
        self.arg = args
    def run(self):
        print("in son",self.arg)
t = Mythread(123)
t.start()

4.threading模块中的其他功能

from threading import Thread,currentThread,activeCount,enumerate
import time
class Mythread(Thread):
    def __init__(self,arg):
        super().__init__()
        self.arg = arg
    def run(self):
        print("in son",self.arg,currentThread)
for i in range(10):
    t= Mythread(123)
    t.start()
    print(t.ident)      
print(activeCount())  
print(enumerate())

enumerate:所有线程对象组成的列表
currentThread “返回当前线程对象,对应于调用方的控制线程。如果调用者的控制线程不是通过线程模块创建的,则返回一个功能有限的虚拟线程对象。     

ident(Self):“此线程的线程标识符(如果没有启动)。这是一个非零整数。请参见get_ident()函数。线程标识符可以在线程退出并创建另一个线程时循环使用。该标识符即使在线程退出之后也可用。
activeCount = active_Count “返回当前活动的线程对象的数量。返回的计数等于枚举()返回的列表的长度。

5.守护线程

守护进程 只守护主进程的代码,主进程代码结束了就结束守护,守护进程在主进程之前结束
守护线程 随着主线程(包含所有非守护的子线程)的结束才结束,守护线程是怎么结束的?

线程内部的代码执行完毕 那么就自动结束了。线程没有强制结束的方法.即没有terminate方法

import time
from threading import Thread
def func1():
    while True:
        print("in func")
        time.sleep(0.5)
def func2():
    print("start func2")
    time.sleep(2)
    print("end func2")
if __name__ == '__main__':
    t1 = Thread(target =func1)
    t2 = Thread(target=func2)
    t1.setDaemon(True)               #将func1设置为守护线程
    t1.start()
    t2.start()
    print("主线程")
    time.sleep(2)
    print("主进程结束")

in func
start func2
主线程
in func
in func
in func
主进程结束
end func2

Process finished with exit code 0

6.0线程池引子    threading模块

import time
from threading import currentThread
from concurrent.futures import ThreadPoolExecutor   
                          #concurrent.futures模块提供了高度封装的异步调用接口
def func(num):
    print("in %s func"%num,currentThread())
    time.sleep(1)
    return num**2
tp= ThreadPoolExecutor(5)     #ThreadPoolExecutor:线程池,提供异步调用
ret_l = []                     #扩展: ProcessPoolExecutor: 进程池,提供异步调用
for i in range(30):
    ret= tp.submit(func,i)     #基本方法   submit(fn,*args,**kwargs)异步提交任务
    ret_l.append(ret)
for ret in ret_l:
    print(ret.result())        #result 提取结果       

6.1线程池

提交任务:submit     阻塞直到任务完成(close+join)shutdown

获取结果 result           简便用法map,异步提交任务            回调函数  add_done_callback 

submit用法
import os
import time
import random
from threading import currentThread
from concurrent.futures import ThreadPoolExecutor
def func(num):
    print('in %s func'%num,currentThread())
    print('in %s func'%num,os.getpid())               #线程池id
    time.sleep(random.random())
    return num**2
if __name__ == '__main__':
    start = time.time()
    tp = ThreadPoolExecutor(5)    #创建一个线程池
# 如果将ThreadPoolExecutor改为ProcessPoolExecutor,则就改成了进程池,其他操作步骤完全一样
    ret_l = []
    for i in range(30):
        ret = tp.submit(func,i)        #提交任务,一次运行5个线程
        ret_l.append(ret)               #将这些线程都加入到列表中
    tp.shutdown()  # close + join   等所有的线程都执行完,再打印下面的结果
    for ret in ret_l:
        print(ret.result())             #result获取结果
in 0 func <Thread(ThreadPoolExecutor-0_0, started daemon 5980)>
in 0 func 2948
in 1 func <Thread(ThreadPoolExecutor-0_1, started daemon 9856)>
in 1 func 2948
in 2 func <Thread(ThreadPoolExecutor-0_2, started daemon 14348)>
in 2 func 2948
in 3 func <Thread(ThreadPoolExecutor-0_3, started daemon 3412)>
in 3 func 2948
in 4 func <Thread(ThreadPoolExecutor-0_4, started daemon 13952)>
in 4 func 2948
......
0
1
4
9
16
......

Process finished with exit code 0

map用法如下,其他程序同上
# if __name__ == '__main__':
#     tp = Pool(2)
#     ret = tp.map(func,range(6))
#     for i in ret:
#         print(i)


回调函数
from threading import currentThread
from concurrent.futures import ThreadPoolExecutor as Pool
def func1(num):
    print('in func1 ',num,currentThread())
    return num*'*'

def func2(ret):
    print('--->',ret.result(),currentThread())
tp = Pool(5)
print('主 : ',currentThread())
for i in range(10):
    tp.submit(func1,i).add_done_callback(func2)
  # 回调函数收到的参数是需要使用result()获取的
  # 回调函数是由谁执行的? 主线程


主 :  <_MainThread(MainThread, started 6628)>
in func1  0 <Thread(ThreadPoolExecutor-0_0, started daemon 10692)>
--->  <Thread(ThreadPoolExecutor-0_0, started daemon 10692)>
in func1  1 <Thread(ThreadPoolExecutor-0_0, started daemon 10692)>
---> * <_MainThread(MainThread, started 6628)>
in func1  2 <Thread(ThreadPoolExecutor-0_0, started daemon 10692)>
---> ** <_MainThread(MainThread, started 6628)>
......

Process finished with exit code 0

总结:ThreadPoolExecutor线程池模块和ProcessPoolExecutor进程池模块中的方法都一样,即在开启的时候只需要改下模块的名字,就能实现相应的功能。不同的是Pool进程池模块不具备这些方法,但Pool和ProcessPoolExecutor都为进程池,实现的功能也相同,只不过方法不同。

    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值