在单个程序中我们经常用多线程来处理不同的工作,尤其是有的工作需要等,那么我们会新建一个线程去等然后执行某些操作,当做完事后线程退出被回收。当一个程序运行时,就会有一个进程被系统所创建,同时也会有一个线程运行,这个线程就是主线程main,在主线程中所创建的新的线程都是子线程,子线程通常都是做一些辅助的事。python中提供了thread和threading两个模块来支持多线程。这篇介绍一下python的多线程和基本使用,下一篇介绍python多线程同步问题。

python中使用线程有两种方式,第一种是用thread模块的start_new_thread函数,另一种是用threading模块的Thread类来包装线程对象。

1.使用thread模块

使用thread模块的start_new_thread函数创建线程并启动。start_new_thread函数原型:

thread.start_new_thread(function, args[, kwargs])

>>> help(thread.start_new_thread)

Help on built-in function start_new_thread in module thread:

start_new_thread(...)

    start_new_thread(function, args[, kwargs])

    (start_new() is an obsolete synonym)

    Start a new thread and return its identifier.  The thread will call the

    function with positional arguments from the tuple args and keyword arguments

    taken from the optional dictionary kwargs.  The thread exits when the

    function returns; the return value is ignored.  The thread will also exit

    when the function raises an unhandled exception; a stack trace will be

    printed unless the exception is SystemExit.

(END)

  

这个函数创建一个新线程,并立刻执行函数function,args是该函数function的参数,是一个元组,kwargs是可选的,它为函数提供了命名参数字典。该函数返回一个整数,为线程标示符。function函数执行完后线程正常退出,如果执行过程中有未处理的异常,线程会异常退出。

thread模块的主要函数:

1).start_new_thread()

创建并启动线程执行function函数,function执行完线程退出,或者遇到未处理的异常线程异常退出。

2).thread.exit()

结束当前线程,会触发SystemExit异常,如果没有捕获处理该异常,线程会退出。

3).thread.get_ident()

得到该线程的标示符,就是新建线程时返回的标示符,是一个整数。

4).thread.interrupt_main

在主线程main中触发一个KeyboardInterrupt异常,子线程用这个函数来终止主线程。

5).thread.allocate_lock()

创建一个锁对象LockType,使多个线程同步访问共享资源。

在python中使用多线程更多的是使用第二种方式,即使用threading模块。

2.使用threading模块

threading模块是对thread模块的第二次封装,提供了更好的API来让我们使用。使用threading实现多线程编程都是使用的Thread类,或者Timer类,Timer是Thread的子类,可以指定时间间隔后在执行某个操作:

 from threading import Timer

 def main():

     print 'timer test!'

 t = Timer(3, main)

 t.start()

使用Thread类有两种方式,一种是直接创建Thread类的实例,另一种方式是自定义类来继承Thread类。使用Thread类的实例,在它的初始化函数__init__中将可调用的对象作为参数传入,Thread的初始化函数__init__原型:

__init__(self, group=None, target=None, name=None, args=(), kwargs=None, verbose=None);

group和verbose不知道是什么东西,target是可调用对象,线程启动后就执行它,name为线程的名字,默认为"Thread-N",N为数字,args和kwargs是调用target是的参数列表和关键字参数。

 from threading import Thread

 def main(a, b):

     print 'a:%d, b:%d' % (a, b)

 Thread(target=main, name='newThread', args=(1, 2)).start()

自定义类来继承Thread类,然后重写run方法实现我们自己的操作。

from threading import Thread

class MyThread(Thread):

    def __init__(self, threadName, a, b):

        Thread.__init__(self, name=threadName)

        self.a = a

        self.b = b

    def run(self):

        print 'a:%d, b:%d' % (self.a, self.b)

myThread = MyThread('newThread', 1, 2)

myThread.start()

逻辑代码是写在run方法中的,但是我们启动线程都是用的start方法,这两个方法是有区别的,如果直接调用run()方法,只是单纯的调用方法,而调用start()方法是将线程从新建状态启动编程就绪状态,等待cpu的调度,这里涉及到线程的几种状态,start()后线程没有立即运行而是编程就绪状态,当得到cpu时间片后编程运行状态,当run方法结束或者有未处理的异常,线程就结束变成死亡状态等待被回收,在运行状态如果遇到资源没有准备好就会变成阻塞状态,当得到资源后再次编程就绪状态等待cpu的调度。

threading模块的主要类:

1).Thread类

上面已经介绍。

2).Timer类

Thread的子类,上面已经介绍。

3).Lock,RLock,Condition类

同步锁,用于多实现线程同步,资源共享的问题。

4).Event类

用于多线程通信。

多线程同步锁Lock,RLock,Condition和多线程通信Event后面在多线程同步再介绍。

threading模块Thread类的主要函数:

1).Thread.getName(),Thread.setName()

获取和设置线程名字。

2).Thread.ident()

获取线程的标示符,是一个整数。

3).Thread.is_alive(),Thread.isAlive()

判断线程是不是活的,即线程是否已经结束。

4).Thread.activeCount()

获取当前活着的所有线程总数,包括主线程main。

5).Thread.join()

使主线程阻塞,知道该子线程执行完或者超时,它有一个参数timeout表示超时时间,默认为None。

6).Thread.setDaemon()

有一个布尔值的参数,默认为False,该方法设置子线程是否随主线程一起结束。

看看join方法和setDaemon方法:

import threading, time

class MyThread(threading.Thread):

    def __init__(self):

        threading.Thread.__init__(self)

    def run(self):

        print 'thread start'

        time.sleep(3)

        print 'thread end'

thread1 = MyThread()

thread1.start()

time.sleep(1)

print 'start join'

#thread1.join()

print 'end join'

输出结果:

不加thread.join

thread start

start join

end join

thread end

加thread.join

thread start

start join

thread end

end join

  主线程中sleep(1)一秒就是为了让线程被调度,线程中sleep(3)三秒就是为了让主线程结束,从两种情况的输出结果可以看出join的功能。

import threading, time

class MyThread(threading.Thread):

    def __init__(self):

        threading.Thread.__init__(self)

    def run(self):

        print 'thread start'

        time.sleep(3)

        print 'thread end'

print 'main start'

thread1 = MyThread()

#thread1.setDaemon(True)

thread1.start()

time.sleep(1)

print 'main end'

  输出结果:

setDaemon默认为False

main start

thread start

main end

thread end

setDaemon设置为True

main start

thread start

main end

  

从打印的结果可以看出,当设置为True的时候,线程还在sleep过程就就结束了,以至于thread end这句都没有打印出来。

当然Thread类还不止这些方法,这些只是常用的方法,通过help(Thread)可以查看。

【python标准库学习】thread,threading(一)多线程的介绍和使用的更多相关文章

  1. python标准库学习-SimpleHTTPServer

    这是一个专题 记录学习python标准库的笔记及心得 简单http服务 SimpleHTTPServer 使用 python -m SimpleHTTPServer 默认启动8000端口 源码: &q ...

  2. Python标准库学习之zipfile模块

    ZipFile模块里有两个非常重要的class, 分别是 ZipFile和ZipInfo. ZipFile是主要的类,用来创建和读取zip文件,而ZipInfo是存储的zip文件的每个文件的信息的. ...

  3. python标准库学习-ftplib

    源码: """An FTP client class and some helper functions. Based on RFC 959: File Transfer ...

  4. python标准库00 学习准备

    Python标准库----走马观花 python有一套很有用的标准库.标准库会随着python解释器一起安装在你的电脑上的.它是python的一个组成部分.这些标准库是python为你准备的利器,可以 ...

  5. Python标准库的学习准备

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! Python标准库是Python强大的动力所在,我们已经在前文中有所介绍.由于标准 ...

  6. Python标准库简介

    在<Python语言参考手册>描述中的描述Python语法和语义,而本手冊主要介绍了Python标准库的内容和使用,也介绍了一些发行库里可选的组件库. Python标准库包括的内容是非常广 ...

  7. Python标准库08 多线程与同步 (threading包)

    Python主要通过标准库中的threading包来实现多线程.在当今网络时代,每个服务器都会接收到大量的请求.服务器可以利用多线程的方式来处理这些请求,以提高对网络端口的读写效率.Python是一种 ...

  8. Python 标准库一览(Python进阶学习)

    转自:http://blog.csdn.net/jurbo/article/details/52334345 写这个的起因是,还是因为在做Python challenge的时候,有的时候想解决问题,连 ...

  9. python 标准库 —— 线程与同步(threading、multiprocessing)

    1. 创建线程 使用 os 下的 fork() 函数调用(仅限 Unix 系统) import os print('current process (%s) starts ...' % (os.get ...

随机推荐

  1. 基于vue2.0打造移动商城页面实践 vue实现商城购物车功能 基于Vue、Vuex、Vue-router实现的购物商城(原生切换动画)效果

    基于vue2.0打造移动商城页面实践 地址:https://www.jianshu.com/p/2129bc4d40e9 vue实现商城购物车功能 地址:http://www.jb51.net/art ...

  2. Python运行出现:ModuleNotFoundError: No module named 'logbook',解决办法

    ModuleNotFoundError: No module named 'xlrd' ModuleNotFoundError: No module named 'xlwt' AttributeErr ...

  3. Resultset获取行数和列数

    在Java中,获得ResultSet的总行数的方法有以下几种. 第一种:利用ResultSet的getRow方法来获得ResultSet的总行数 Statement stmt = con.create ...

  4. Hadoop本地环境安装

    一.服务器环境 本人用的是阿里云的ECS的入门机器,配置1核2G,1M带宽,搭了个Hadoop单机环境,供参考 Linux发行版本:Centos7 JDK:阿里云镜像市场中选择JDK8 二.安装步骤 ...

  5. java 多线程 线程安全及非线程安全的集合对象

    一.概念: 线程安全:就是当多线程访问时,采用了加锁的机制:即当一个线程访问该类的某个数据时,会对这个数据进行保护,其他线程不能对其访问,直到该线程读取完之后,其他线程才可以使用.防止出现数据不一致或 ...

  6. python实现WordCount(第三次作业)

    0x00 注明 合作者:201631062315 201631062310 代码地址:https://gitee.com/c1e4r/word-count2 作业地址:https://edu.cnbl ...

  7. Linux系统测试端口连通性的方法

    Linux系统测试端口连通性的方法 有四种常用方法:1. telnet 方法2. wget 方法3. ssh 方法4. curl 方法 下面一一介绍. 1. telnet用法: telnet ip p ...

  8. Codeforces 358D DP

    题意:有n只兔子需要喂养,每只兔子被喂养后的幸福感取决于与它相邻的兔子中已经被喂养的数量.现在问喂养这n只兔子可以获得的总幸福感最多是多少? 思路:初步分析题目发现,一只兔子被喂养获得的幸福感取决于其 ...

  9. 力扣—Remove Nth Node From End of List(删除链表的倒数第N个节点) python实现

    题目描述: 中文: 给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点. 示例: 给定一个链表: 1->2->3->4->5, 和 n = 2. 当删除了倒数第二 ...

  10. webpack 学习4 使用loader 以及常用的一些loader

    webpack本身只支持处理JavaScript,其他的文件,如css img less是不识别的,所以才会有loader这个东西,它就是可以使webpack能够处理其他非js文件的拓展程序 首先我们 ...