Python中使用threading模块来实现多线程

threading提供一些常用的方法

threading.currentThread()   返回当前的线程变量
threading.enumerate() 返回一个正在运行的线程的list
threading.activeCount() 返回正在运行的线程数量,与len(threading.enumerate()) 有相同的结果。
threading.TIMEOUT_MAX 设置threading全局超时时间。

threading模块提供Thread类的各种同步原语,用于编写多线程程序

Thread对象

Thread 类用于表示单独的控制线程,使用下面的函数可以创造一个新线程

Thread(group=None, target=None, name=None, arg=(), kwarg={})

此函数创造一个新的Thread实例。

group  值是None,为以后扩展而保留

target 是一个可调用对象,线程启动时 run()方法将调用此对象,他的默认值是None,表示不调用任何内容

name   是线程名称,默认创建一个"Thread-N"格式的唯一名称

args   是传递给target函数的参数元组

kwargs 是传递给target的关键字参数的字典

Thread实例t支持一下方法和属性

t.start()
通过在一个单独的控制线程中调用run()方法,启动线程。此方法只能用调用一次 t.run()
线程启动时将调用此方法。默认情况下,他将调用传递到构造函数中的目标函数。还可以在Thread的子类中重新定义此方法 t.join()
等待直到线程终止或者出现超时为止。timeout是一个浮点数,用于指定以秒为单位的超时时间
线程不能连接自身,而且在线程启动之前就连接它将出现错误。 t.is_alive()
如果线程是活动的,返回True,否则返回False。从start()方法返回的那一刻开始,线程就是活动的,知道它的run()方法终止。
t.isAlive()是老式代码中此方法的别名 t.name
线程名称。这个字符串用于唯一识别,可以根据需要将他改为更有意义的值,在老式代码中,t.getName()和t.setName(name)
函数用于操作线程名称 t.ident
整数线程标识符。如果线程尚未启动,值为None t.daemon
线程的布尔型后台标志。必须在调用start()方法之前设置这个标志,它的初始值从创造线程的后台状态继承而来。。当不存在任何活动
的非后台线程时,整个Python程序将退出。所有程序都有一个主线程,代表初始的控制线程,他不是后台线程。在老式代码中
t.setDaemon(flag)和t.isDaemon() 函数用于操作这个值

threading实现多线程有两种方法

1. 以线程的形式创建和启动一个函数

 import threading
import time def clock(interval):
while True:
print("The time is %s" % time.ctime())
time.sleep(interval) t = threading.Thread(target=clock, name='clock', args=(3,))
t.start()

2. 将同一个线程定义为一个类, 并重写run()方法

 import threading
import time class ClockThread(threading.Thread):
def __init__(self, interval):
threading.Thread.__init__(self)
self.interval = interval def run(self):
while True:
print("The time is %s" % time.ctime())
time.sleep(self.interval) t = ClockThread(2)
t.start()

如果将线程定义为类,并且定义自己的__init__()方法,必须想上面这个调用基类构造函数Thread.__init__()。

如果忘记这一点,将导致严重错误。除run()方法之外,改写线程已经定义的其他方法也会出现错误

demon=True,线程在后台运行。主程序结束后后台线程无论是否执行完成都将被销毁

 import threading
import time def action(arg):
time.sleep(3)
print(arg) for i in range(1, 4):
t = threading.Thread(target=action, args=(i,))
t.daemon = True # 设置线程为后台线程
t.start() print('thread end!')
time.sleep(1)

执行结果为:thread end!

程序在执行完print('thread end!')后暂停一秒才会退出解释器,而后台线程需要三秒后才能打印出数据。
daemon=True时后台线程还未来得及完成运行,就因为主程序的退出而被销毁。

join() 主程序等待所有线程执行完毕后再退出

 import threading
import time start_time = time.time() def action(arg):
time.sleep(3)
print(arg) for i in range(1, 4):
t = threading.Thread(target=action, args=(i,))
t.daemon = True # 设置线程为后台线程
t.start()
t.join() print('thread end!')
time.sleep(5)
stop_time = time.time()
print(stop_time-start_time)

运行结果为:

1
2
3
thread end!
14.007635116577148

从运行结果和运行时间来看,此时程序只能顺序执行,每个线程都被上一个线程的join阻塞,失去了多线程的意义.不加join()时运行时间仅为5.0011246秒

join()设置超时时间,当线程运行时间超过timeout时间时运行下一步

import threading
import time def test1():
print('start 1: ' + time.strftime('%H:%M:%S') + "\n")
time.sleep(6)
print('stop 1: ' + time.strftime('%H:%M:%S') + "\n") def test2():
print('start 2: ' + time.strftime('%H:%M:%S') + "\n")
time.sleep(1)
print('stop 2: ', time.strftime('%H:%M:%S') + "\n") threads = []
t1 = threading.Thread(target=test1)
t1.start()
threads.append(t1) t2 = threading.Thread(target=test2)
t2.start()
threads.append(t2) print('start join: ' + time.strftime('%H:%M:%S') + "\n")
for tt in threads:
tt.join(2)
print('end join: ' + time.strftime('%H:%M:%S') + "\n")

当test1运行时超过了timeout时间2秒,就开始运行test2和print()

Timer对象

Timer对象用于在稍后的某个时间执行一个函数

Timer(interval, func[,args [,kwargs]])

创建定时器对象,在过去interval秒时间之后运行函数func.args和kwargs提供传递给func的参数和关键字参数.在调用start()方法后才会启动定时器

Timer对象t具有以下方法

t.start()      启动定时器.提供给Timer()方法的函数func将在指定的时间间隔之后执行.
t.cancel()   如果函数尚未执行,取消定时器

 import threading

 def func():
print('hello world') t = threading.Timer(5, func)
t.start()
t.cancel() # cancel取消了线程的执行,func不会执行

Python多线程笔记(一)的更多相关文章

  1. Python多线程笔记(三),queue模块

    尽管在Python中可以使用各种锁和同步原语的组合编写非常传统的多线程程序,但有一种首推的编程方式要优于其他所有编程方式即将多线程程序组织为多个独立人物的集合,这些任务之间通过消息队列进行通信 que ...

  2. python 多线程笔记(5)-- 生产者/消费者模式

    我们已经知道,对公共资源进行互斥访问,可以使用Lock上锁,或者使用RLock去重入锁. 但是这些都只是方便于处理简单的同步现象,我们甚至还不能很合理的去解决使用Lock锁带来的死锁问题. 要解决更复 ...

  3. python 多线程 笔记(一)

    #coding=utf-8 import threading from time import sleep, ctime loops = [4,2] def loop(nloop, nsec): pr ...

  4. python 多线程笔记(6)-- 闭包

    在类里弄一个闭包出来 很多资料上说,类内部的变量有两种. 按定义所在的位置,分__init__上方的和__init__下方的 按内存所在的位置,分类的和实例的,或者说公共的和私有的 现在,我想在类里定 ...

  5. python 多线程笔记(6)-- 生产者/消费者模式(续)

    用 threading.Event() 也可以实现生产者/消费者模式 (自己拍脑袋想出来的,无法知道其正确性,请大神告知为谢!) import threading import time import ...

  6. python 多线程笔记(4)-- 车站售票模拟

    import threading import time import random class Worker(threading.Thread): '''售票员''' def __init__(se ...

  7. python 多线程笔记(3)-- 线程的私有命名空间

    线程的私有命名空间实现: threading_namespace = threading.local() import threading import time import random thre ...

  8. python 多线程笔记(2)-- 锁

    锁是什么?什么场合使用锁? 锁是一种机制,用于保护那些会引起冲突的资源. 比如上厕所,进去之后第一件事干嘛?把厕所门反锁!表示什么呢?表示这个厕所正在使用中! 至于在厕所里面干大事.干小事.还是打飞机 ...

  9. python 多线程笔记(1)-- 概念

    本文对不使用线程和使用线程做了一个对比. 假设有两件事情:听歌.看电影 一.不用线程 import time songs = ['爱情买卖','朋友','回家过年','好日子'] movies = [ ...

随机推荐

  1. windows下捕获本地回环网络中的报文RawCap

    一.下载地址: 官网地址:https://www.netresec.com/?page=RawCap 百度云:链接:https://pan.baidu.com/s/1mWCOTRF5XicuJitBA ...

  2. Eclipse RCP使用SWT.EMBEDDED方式显示batik的svgCanvas后窗口最大化变白问题

    // 设置svg组件一直动态(这一行代码导致了最大化变白的问题)svgCanvas.setDocumentState(JSVGCanvas.ALWAYS_DYNAMIC);// 以下两行解决最大化变白 ...

  3. JMeter-03-元件的作用域与执行顺序

    JMeter元件的作用域与执行顺序 元件的作用域 先来讨论一下元件有作用域.<JMeter基础元件介绍>一节中,我们介绍了8类可被执行的元件(测试计划与线程组不属于元件),这些元件中,取样 ...

  4. sqlserver-order by offset fetch

    若要使用 OFFSET 和 FETCH 在查询请求之间获得稳定的结果,必须满足以下条件: 查询使用的基础数据不能发生变化. 即,不会更新查询处理的行,也不会在单个事务中使用快照或可序列化事务隔离执行查 ...

  5. 关于/var/log/maillog 时间和系统时间不对应的问题 -- 我出现的是日志时间比系统时间慢12个小时

    那么让我们来见证奇迹的时刻吧!! 首先你要看下/etc/localtime的软连接,到哪了 一般就是这块出问题了 检查这里就绝对不会错的 对比图 : 这种情况, 删除/etc/localtime : ...

  6. 数据结构与算法(周测3-Huffman树)

    判断题 1.Given a Huffman tree for N (≥2) characters, all with different weights. The weight of any non- ...

  7. jQuery遍历(3)

    上期我们讲了遍历的祖先.后代和同胞的问题,现在我们讲讲遍历遍历过滤 三个最基本的过滤方法是:first(), last() 和 eq(),它们允许您基于其在一组元素中的位置来选择一个特定的元素.其他过 ...

  8. Extjs 兼容IE8常见问题及解决方法

    1. 在IE8中整个页面都打不开,一般情况是: 页面组件中最后一个属性出现了逗号 没有多余的逗号,就很有可能是组件中没有设置renderTo:Ext.getBody(); 2. 页面按钮颜色失效 自定 ...

  9. python 复制列表

    python的变量仅仅是指向对象的标签,所以在操作列表的时候,list1 = list2这种做法只会复制一个标签,然后指向对象,并非生成一个新的对象. 大致有5中方法可以复制列表: a = [1,2, ...

  10. (转)使用SDWebImage和YYImage下载高分辨率图,导致内存暴增的解决办法

    http://blog.csdn.net/guojiezhi/article/details/52033796