python线程代码_Python全栈开发:线程代码实例

#进程与线程的关系

"""

多进程(主进程,子进程):

优点:能同时利用多个CPU,进行多个操作,提高效率。

缺点:耗费内存资源(进程要开辟内存空间),进程不是越多越好,CPU个数 = 进程个数。

注意:进程创建内存空间,线程共享内存空间,进程里有全局解释器锁,进程中一次只应许一个线程被处理。

使用场景:计算密集型适合多进程。

多线程(主线程,子线程):

优点:共享内存,IO操作时(不用CPU),创造并发操作(多个操作同时进行),提高效率。

缺点:抢占资源,请求上下文切换非常耗时(线程处理切换后找到上次处理的地方),线程不是越多越好,视具体案例而定。

注意:在计算机中,执行任务的最小单元就是线程。

使用场景:IO密集型适合多线程。

"""

"""

队列queue

先进先出,一边放,另一边取

可设置最大个数,get等待,get_nowait不等待

"""

"""

使用线程

1、创建线程

import threading

import time

def f1():

pass

def f2(a1, a2):

time.sleep(10)

pass

t = threading.Thread(target=f1, args=(11,22,33))

t.start() # 线程开始跑,创建的是子线程

2、线程锁

防止出现脏数据,一个线程读取数据并对其加锁,CPU切换线程后其他线程不能读取数据,

3、线程池

Python内部没有提供线程池,需要自定义

"""

import threading

import time

def f1():

pass

def f2(a1, a2):

time.sleep(10)

pass

t1 = threading.Thread(target=f2, args=(11, 22))

t1.setDaemon(True) # 主线程是否等待子线程

t1.start() # 线程开始跑,创建的是子线程

print("第一次等待中")

t1.join(2) # 主线程等待子线程多久,不加参数无限等待

t2 = threading.Thread(target=f2, args=(11, 22))

t2.setDaemon(True)

t2.start() # 线程开始跑,创建的是子线程

print("第二次等待中")

t2.join(2) # 主线程等待子线程的执行的最多等待时间,超过时间,主线程继续执行下一部分

t3 = threading.Thread(target=f2, args=(11, 22))

t3.setDaemon(True) # 主线程执行完(解释器执行代码),是否等待子线程执行完再关闭,True:不等待:False:等待。默认为False

t3.start() # 线程开始跑,创建的是子线程

线程event

#!/usr/bin/env python

# -*- coding;utf-8 -*-

"""

线程event

"""

import threading

import time

def do(event):

print("线程前半部分")

event.wait() # 阻塞(十字路口),红灯则等待,绿灯则继续执行

print("线程后半部分")

event_obj = threading.Event()

for i in range(10):

t = threading.Thread(target=do, args=(event_obj,))

t.start()

# 耗时十分钟

# time.sleep(10)

event_obj.clear() # 让灯变红

inp = input("请输入内容:>>>")

if inp == "true":

event_obj.set() # 让灯变绿,线程就都可以继续执行

线程数据共享

#!/usr/bin/env python

# -*- coding;utf-8 -*-

"""

默认情况下线程数据不共享

线程与线程之间数据可以共享

"""

from threading import Thread

li = []

def foo(i):

li.append(i)

print("hello", li)

if __name__ == "__main__":

for i in range(10):

t = Thread(target=foo, args=(i,))

t.start()

线程池

简单线程池

#!/usr/bin/env python

# -*- coding;utf-8 -*-

"""

自定义线程池博客园教程地址

http://www.cnblogs.com/wupeiqi/articles/4839959.html

"""

import queue

import threading

import time

class ThreadPool(object):

def __init__(self, max_num=20):

self.queue = queue.Queue(max_num)

for i in range(max_num):

self.queue.put(threading.Thread)

def get_thread(self):

return self.queue.get()

def add_thread(self):

self.queue.put(threading.Thread)

def func(i, arg):

print(i)

time.sleep(4)

# 在队列中增加线程类

arg.add_thread()

if __name__ == "__main__":

# 在队列中创建线程类

pool = ThreadPool(10)

for i in range(30):

# 获得类

thread = pool.get_thread()

# 对象 = 类()

ret = thread(target=func, args=(i, pool))

ret.start()

高级线程池

#!/usr/bin/env python

# -*- coding;utf-8 -*-

import threading

import time

import queue

import contextlib

StopEvent = object()

class Threadpool(object):

def __init__(self, max_num):

self.max_num = max_num

# 创建任务队列

self.queue = queue.Queue()

self.terminal = False

# 表示真实创建的线程列表

self.generate_list = []

# 表示空闲的线程列表

self.free_list = []

def run(self, func, args, callback=None):

"""

线程池执行一个任务

:param func: 执行任务的函数

:param args: 任务函数的参数(以元组形式存在的任务包,封装了几个参数)

:param callback: 任务执行失败或者成功后执行的回调函数,回调函数有两个参数

:return:

"""

# 往任务队列里加任务

w = (func, args, callback)

self.queue.put(w)

# 如果空闲线程等于零并且真实创建的线程数小于任务数

if len(self.free_list) == 0 and len(self.generate_list) < self.max_num:

self.generate_thread()

def generate_thread(self):

"""

创建一个线程

:return:

"""

t = threading.Thread(target=self.call)

t.start()

def call(self):

"""

循环去获取任务函数并执行任务函数

:return:

"""

current_thread = threading.current_thread()

self.generate_list.append(current_thread)

# 去任务并执行

event = self.queue.get()

while event != StopEvent:

# 如果是元组任务,解开任务包,执行任务

func, args, callback = event

try:

ret = func(*args)

success = True

except Exception as e:

success = False

ret = e

if callback is not None:

try:

callback(success, ret)

except Exception as e:

pass

with self.work_station(self.free_list, current_thread):

if self.terminal:

event = StopEvent

else:

event = self.queue.get()

else:

self.generate_list.remove(current_thread)

def close(self):

# 中途终止线程

num = len(self.generate_list)

while num:

self.queue.put(StopEvent)

num -= 1

def terminate(self):

# 终止线程(不清空队列),线程一直在等待拿,程序不会退出

"""

终止线程(清空队列)

while self.generate_list:

self.queue.put(StopEvent)

"""

self.terminate = True

max_num = len(self.generate_list)

# self.queue.empty()

while max_num:

max_num = len(self.generate_list)

max_num -= 1

#self.queue.empty()

@contextlib.contextmanager

def work_station(self, station, val):

station.append(val)

try:

yield

finally:

station.remove(val)

def work(i):

# time.sleep(3)

print(i)

pool = Threadpool(10)

for i in range(50):

pool.run(func=work, args=(i,), callback=None)

# pool.terminate()

pool.close()

绝版线程池

#!/usr/bin/env python

# -*- coding;utf-8 -*-

"""

自定义线程池博客园教程地址

http://www.cnblogs.com/wupeiqi/articles/4839959.html

"""

import queue

import threading

import contextlib

import time

StopEvent = object()

class ThreadPool(object):

def __init__(self, max_num, max_task_num = None):

if max_task_num:

self.q = queue.Queue(max_task_num)

else:

self.q = queue.Queue()

self.max_num = max_num

self.cancel = False

self.terminal = False

self.generate_list = []

self.free_list = []

def run(self, func, args, callback=None):

"""

线程池执行一个任务

:param func: 任务函数

:param args: 任务函数所需参数

:param callback: 任务执行失败或成功后执行的回调函数,回调函数有两个参数1、任务函数执行状态;2、任务函数返回值(默认为None,即:不执行回调函数)

:return: 如果线程池已经终止,则返回True否则None

"""

if self.cancel:

return

if len(self.free_list) == 0 and len(self.generate_list) < self.max_num:

self.generate_thread()

w = (func, args, callback,)

self.q.put(w)

def generate_thread(self):

"""

创建一个线程

"""

t = threading.Thread(target=self.call)

t.start()

def call(self):

"""

循环去获取任务函数并执行任务函数

"""

current_thread = threading.currentThread()

self.generate_list.append(current_thread)

event = self.q.get()

while event != StopEvent:

func, arguments, callback = event

try:

result = func(*arguments)

success = True

except Exception as e:

success = False

result = None

if callback is not None:

try:

callback(success, result)

except Exception as e:

pass

with self.worker_state(self.free_list, current_thread):

if self.terminal:

event = StopEvent

else:

event = self.q.get()

else:

self.generate_list.remove(current_thread)

def close(self):

"""

执行完所有的任务后,所有线程停止

"""

self.cancel = True

full_size = len(self.generate_list)

while full_size:

self.q.put(StopEvent)

full_size -= 1

def terminate(self):

"""

无论是否还有任务,终止线程

"""

self.terminal = True

while self.generate_list:

self.q.put(StopEvent)

self.q.queue.clear()

@contextlib.contextmanager

def worker_state(self, state_list, worker_thread):

"""

用于记录线程中正在等待的线程数

"""

state_list.append(worker_thread)

try:

yield

finally:

state_list.remove(worker_thread)

# How to use

pool = ThreadPool(5)

def callback(status, result):

# status, execute action status

# result, execute action return value

pass

def action(i):

print(i)

if __name__ == "__main__":

for i in range(30):

ret = pool.run(action, (i,), callback)

time.sleep(0.01) # 等待的时间xiao'l

print(len(pool.generate_list), len(pool.free_list))

print(len(pool.generate_list), len(pool.free_list))

pool.close() # 子线程结束时,主线程就结束,time.sleep后的内容可能没有结果

# pool.terminate()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值