python多核多线程编程_Python3并发编程之多线程

并发:假同时,一段时间内同时处理多个任务

并行:真同时,同时处理多个任务,必须多核,是并发的子集

threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)

线程

import threading

def worker():

print('work')

thread = threading.Thread(target=worker) # 创建线程对象,target参数是一个函数,这个函数即线程要执行的逻辑

thread.start() # start函数启动一个线程,当这个线程的逻辑执行,设计自动退出,自己退出。

import time

def worker(num):

time.sleep(1)

print('worker-{}'.format(num))

for z in range(5):

t = threading.Thread(target=worker, args=(z, )) # 元组参数列表

t.start()

如何标识一个线程

threading.current_thread() # 返回当前线程

<<<_MainThread(MainThread, started 140428986173248)>

thread = threading.current_thread()

thread.name # 线程名,可重名

<<'MainThread'

thread.ident # 线程id

<<140428986173248

logging

import logging

logging.warning('haha')

<

import importlib

importlib.reload(logging) # 重新引入,覆盖缓存

# import导入一次会在缓存中固定,,reload会从标准库中导入

logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s %(threadName)s %(message)s') # 配置logging

logging.warning('haha') # 替代print

<<2017-03-11 09:42:47,814 WARNING [MainThread haha]

参数

# 通过args参数传递位置参数,通过kwargs传递关键字参数

def add(x, y):

logging.info(x + y)

add(1, 2)

add(x=1, y=2)

threading.Thread(target=add, args=(1, 2)).start()

threading.Thread(target=add, kwargs={'x':1, 'y':2}).start()

threading.Thread(target=add, args=(1,), kwargs={'y':2}).start()

<<2017-03-11 09:45:23,651 INFO [Thread-18 3]

线程名

threading.Thread(target=add, args=(1, 2), name='adc').start()

2017-03-11 09:47:55,442 INFO [adc 3]

# 通过name参数设置线程名字,日志可以带线程名

# 线程可以重名,唯一标识符是id,但是通常应该避免线程重名。通常线程名命名加前缀

线程通信的必要

importlib.reload(logging)

logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s [%(threadName)s %(message)s]')

def ww(num):

logging.info('ww-{}--'.format(num))

time.sleep(1)

logging.info('ww-{}'.format(num))

for i in range(5):

t = threading.Thread(target=ww, args=(i, ), name='ww1')

t.start()

for i in range(5):

t = threading.Thread(target=ww, args=(i, ), name='ww2')

t.start()

<<2017-03-11 10:24:58,067 INFO [ww1 ww-0--]

<<2017-03-11 10:24:58,071 INFO [ww1 ww-1--]

<<2017-03-11 10:24:58,074 INFO [ww1 ww-2--]

<<2017-03-11 10:24:58,076 INFO [ww1 ww-3--]

<<2017-03-11 10:24:58,078 INFO [ww1 ww-4--]

<<2017-03-11 10:24:58,081 INFO [ww2 ww-0--]

<<2017-03-11 10:24:58,084 INFO [ww2 ww-1--]

<<2017-03-11 10:24:58,086 INFO [ww2 ww-2--]

<<2017-03-11 10:24:58,105 INFO [ww2 ww-3--]

<<2017-03-11 10:24:58,121 INFO [ww2 ww-4--]

<<2017-03-11 10:24:59,073 INFO [ww1 ww-0]

<<2017-03-11 10:24:59,074 INFO [ww1 ww-1]

<<2017-03-11 10:24:59,077 INFO [ww1 ww-2]

<<2017-03-11 10:24:59,080 INFO [ww1 ww-3]

<<2017-03-11 10:24:59,082 INFO [ww1 ww-4]

<<2017-03-11 10:24:59,086 INFO [ww2 ww-0]

<<2017-03-11 10:24:59,087 INFO [ww2 ww-1]

<<2017-03-11 10:24:59,106 INFO [ww2 ww-2]

<<2017-03-11 10:24:59,122 INFO [ww2 ww-3]

<<2017-03-11 10:24:59,130 INFO [ww2 ww-4]

# 多线程自动并发,各线程调度顺序需要进程间通信来控制

daemon

# 在pycharm中

import time

import logging

import threading

logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)s [%(threadName)s %(message)s]')

def worker1():

logging.info('starting')

time.sleep(20)

logging.info('completed')

def worker2():

logging.info('starting')

time.sleep(3)

logging.info('completed')

if __name__ == '__main__':

logging.info('start1')

t = threading.Thread(target=worker1, name='non-daemon')

t.start()

t = threading.Thread(target=worker2, daemon=True, name='daemon')

t.start()

logging.info('stop1')

<<2017-03-11 11:30:08,007 INFO [MainThread start1]

<<2017-03-11 11:30:08,026 INFO [non-daemon starting]

<<2017-03-11 11:30:08,044 INFO [daemon starting]

<<2017-03-11 11:30:08,045 INFO [MainThread stop1]

<<2017-03-11 11:30:11,048 INFO [daemon completed]

<<2017-03-11 11:30:28,040 INFO [non-daemon completed]

# daemon参数默认False

# daemon标记的子线程会随父线程退出而退出,可能执行完,可能未执行完

# none-daemon标记的子线程,主线程会等待其执行完再退出

依靠时间片解述:

125157_FSdb_2698055.png

125208_e5Tv_2698055.png

join

# join方法会阻塞,直到线程退出或者超时,timeout 是可选的,如果不设置timeout,会一直等待线程退出。不占用CPU时间

# 可用来强制等待deamon线程执行完成

t.join()

# 默认等待退出

t.join(timeout)

# 等待超时

thread local

del(thread) # 删除对象

ctz = threading.local()

ctz.data = 5

data = 'abc'

def worker():

logging.info(data)

logging.info(ctz.data)

worker()

<<2017-03-11 11:19:16,158 INFO [MainThread abc]

<<2017-03-11 11:19:16,173 INFO [MainThread 5]

threading.Thread(target=worker).start()

<<2017-03-11 11:21:12,623 INFO [Thread-23 abc]

# threading.local()增加的属性只存在当前线程,只对当前线程可见

定时器/延迟执行

def worker():

logging.info('run')

t = threading.Timer(interval=5, function=worker) # 用function不是target

t.start() # 停顿5秒 执行,没有name

t.name

<<'Thread-28'

<<2017-03-11 11:37:50,080 INFO [Thread-28 run]

t.name = 'worker' # 这样设置name

t.start()

t.cancel()

# 取消执行,线程结束。 在start后,在interval内,之间存在

threading.enumerate() # 查看当前所有线程

def worker():

logging.info('starting')

time.sleep(30)

logging.info('completed')

t = threading.Timer(interval=0, function=worker)

t.start()

<<2017-03-11 11:45:50,224 INFO [Thread-32 starting]

t.cancel()

t.is_alive()

<

<<2017-03-11 11:46:20,248 INFO [Thread-32 completed]

# 当function参数指定函数开始执行的时候,cancel无效,无法取消

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值