一、全局锁

1、在Python中,Python代码的执行由Python虚拟机来控制,而在Python虚拟机中,同一时刻只有一个线程在执行,就像单CPU的系统中运行多个进程那样,内存中可以存放多个程序,但在任意时刻,只有一个程序在CPU中运行。同样的,在Python解释器中可以“运行”多个线程,但在任意时刻,只有一个线程在Python解释器中运行。

2、对Python虚拟机的访问由全局解释器锁【GIL】来控制,正是这个锁能保证同一时刻只有一个线程在运行。

3、多线程环境中,Python虚拟机的执行方式为:

1. 设置GIL

2. 切换到一个线程去运行

3. 运行:

a. 指定数量的字节码指令,或者

b. 线程主动让出控制(可以调用time.sleep(0)

4. 把线程设置为睡眠状态

5. 解锁GIL

6. 再次重复以上所有步骤

二、线程模块

Python提供了【thread】和【threading】模块。在多线程编程中,建议使用【threading】模块,这是因为:

1、在【thread】模块中,当主线程退出时,其他没有被清除的线程没有运行结束就会被退出。但在【threading】模块中能确保所有的“重要的”子线程(这里的重要的子线程指的是守护线程)运行结束后,进程才会结束

2、在【threading】模块是更高级的线程模块,它不仅提供了Thread类,还提供了线程同步机制

thread模块

内建函数

1、thread.start_new_thread(function, args[, kwargs=None])

这个函数用来启动一个线程,其参数含义分别为:

function:线程任务函数

args:线程任务函数的参数【以元组的方式传入】

kwargs:可选的参数

2、thread.interrupt_main()

这个函数用来中断主线程

3、thread.exit()

这个函数用来退出线程

4、thread.get_ident()

这个函数用来获取线程标识号

5、thread.allocate_lock()

这个线程用来获取LockType对象

6、thread.stack_size([size])

这个线程用来返回创建新线程栈容量,其参数含义为:

size:指定创建新线程栈容量,该参数取值为0或不小于32,768(32KB)

LockType对象

1、lock.acquire([waitflag])

这个函数用来申请锁对象,若是获得锁对象返回True,否则返回False

2、lock.release()

这个函数用来释放锁对象【使用该函数前提是获取锁对象】

3、lock.locked()

这个函数用来获取对象锁的状态,若是已被锁住则返回True,否则返回False

示例:
>>> import thread

>>> sum = 0

/*****************线程任务函数**********************/

>>> def add(lock):

    global sum               #设置为全局变量

    lock.acquire()          #加锁

    i = 1

    while(i < 3):

        sum = sum + 10

        i = i + 1

    id = thread.get_ident() #线程号

    print "Thread ",id,"set sum = ",sum

lock.release()          #释放锁

/***********************启动线程**************************/

>>> def startTask():

    lock = thread.allocate_lock() #申请锁对象

    task_0 = thread.start_new_thread(add,(lock,))

    task_1 = thread.start_new_thread(add,(lock,))

/************************测试**************************/

>>> startTask()

>>> Thread  764 set sum =  20

Thread  5240 set sum =  40

threading模块

【threading】模块式以【thread】为基础,但提供更高的线程类以及同步机制。

内建函数

1、threading.activeCount()

这个函数用来获取【active Thread】的数目

2、threading.enumerate()

这个函数用来获取【active Thread】列表。注意:包括中断的线程以及还未开始的线程

3、threading.currentThread()

这个函数用来获取当前运行的【Thread object】

4、threading.settrace(func)

这个函数用来设置所有通过【threading】模块启动的线程的跟踪函数,该函数在【Thread Object】的【run】方法执行前被调用,其参数含义为:

func:跟踪函数名

5、threading.setprofile(func)

这个函数用来设置所有通过【threading】模块启动的线程的profile函数

6、threading.Event()

这个工厂函数用来获取一个新的【Event Object】

7、threading.Lock()

这个工厂函数用来获取【LockType Object】

8、threading.RLock()

这个工厂函数用来获取【RLock Object】

9、threading.Condition()

这个工厂函数用来获取【Condition Object】

10、threading.Semaphore([value])

这个工厂函数用来获取【Semaphore Object】

11、threading.BoundedSemaphore([value])

这个工厂函数用来获取【Bounded Semaphore Object】

内建类

1、class threading.local

类似Java的ThreadLocal

2、class threading.Thread(group=None, target=None, name=None,             

                                            args=(), kwargs={})

构造函数参数含义如下:

target:Thread类中【run】函数调用的函数

name:指定线程的名,默认线程名格式为:【Thread-N】

args:target函数的参数

1)、start()

启动线程,值得注意的是:该方法只能被线程调用一次,否则抛出异常RuntimeError

2)、run()

线程任务函数。常被子类重写,类似Java Thread类的run函数

3)、is_alive()

判断线程是否【alive】

4)、setDaemon()

将线程设置为守护线程

3、class threading.Timer(interval, function, args=[], kwargs={})

Timer类继承threading.Thread类,其参数含义为:

interval:线程时间执行时间间隔,以秒为单位

function:Thread类中run函数执行的目标函数

args:目标函数的参数

1)、cancel()

取消Timer任务的执行

示例
/***************************Timer实例************************/

>>> def putOutNumber():

    id = threading.currentThread().getName()

    print id,'Hello'

>>> def startTimer():

    timer = threading.Timer(60,putOutNumber)

    timer.start()

>>> startTimer()

>>> Thread-1 Hello

/****************继承Thread与Semaphore实例********************/

>>> import threading

>>> class MyThread(threading.Thread):

    def __init__(self,name,semaphore):

        threading.Thread.__init__(self,None,None,name,None)

        self.semaphore = semaphore

    def run(self): #override run function

        self.semaphore.acquire()

        i = 1

        while(i < 3):

            print self.getName(),' print ',i

            i = i + 1

        self.semaphore.release()

>>> def startTask():

    semaphore = threading.Semaphore()

    thread_0 = MyThread("Thread_0",semaphore)

    thread_1 = MyThread("Thread_1",semaphore)

    thread_0.start()

    thread_1.start()

>>> startTask()

>>> Thread_0  print  1

    Thread_0  print  2

    Thread_1  print  1

    Thread_1  print  2

/*********************进程之间进行通信************************/

>>> class ManagerThread(threading.Thread):

    def __init__(self,name,event):

        threading.Thread.__init__(self,None,None,name,None)

        self.event = event

    def run(self): #override run function

        print self.getName(),' say ','go'

        self.event.set()

>>> class PeopleThread(threading.Thread):

    def __init__(self,name,event):

        threading.Thread.__init__(self,None,None,name,None)

        self.event = event

    def run(self):

        self.event.wait()

        print self.getName(),' start ','go'

>>> def startTask():

    event = threading.Event()

    m_thread = ManagerThread("Manager",event)

    p_thread = PeopleThread("People",event)

    p_thread.start()

m_thread.start()

/*************************测试****************************/

>>> startTask()

>>> Manager  say  go

    People  start  go

Mutex

内建类

1、class mutex.mutex

mutex对象有两个属性:锁和队列。当锁没有被锁时,队列是空的。

/*********************mutex Object 函数********************/

1)、mutex.test()

这个函数检测mutex是否被锁

2)、 mutex.testandset()

这个函数用来检测mutex是否被锁,若是没有锁住,则锁住并返回True,否则返回False。值得注意的是:这个函数是原子操作

3)、mutex.lock(function, argument)

这个函数用来执行函数function(argument)【前提是mutex没有被锁】。如果mutex锁被锁,则将function(argument)放入队列中

4)、mutex.unlock()

这个函数用来解锁mutex【前提是队列是空的】。如果队列不是空的,则在队列中取出第一个function(argument)执行并不解锁

示例
>>> import mutex

>>> def putOutTask(text):

     print text

>>> def startTask():

    m_metux = mutex.mutex()

    m_metux.lock(putOutTask,'I am task_0')

    m_metux.lock(putOutTask,'T am task_1')

    m_metux.lock(putOutTask,'I am task_2')

    m_metux.lock(putOutTask,'T am task_3')

    m_metux.lock(putOutTask,'I am task_4')

    m_metux.lock(putOutTask,'T am task_5')

    while(m_metux.test()):

        m_metux.unlock()

m_metux.unlock()

/**************************测试***************************/

>>> startTask()

I am task_0

T am task_1

I am task_2

T am task_3

I am task_4

T am task_5

Python线程操作的更多相关文章

  1. Python程序中的线程操作(线程池)-concurrent模块

    目录 Python程序中的线程操作(线程池)-concurrent模块 一.Python标准模块--concurrent.futures 二.介绍 三.基本方法 四.ProcessPoolExecut ...

  2. [ python ] 线程的操作

    目录 (见右侧目录栏导航) - 1. 前言    - 1.1 进程    - 1.2 有了进程为什么要有线程    - 1.3 线程的出现    - 1.4 进程和线程的关系    - 1.5 线程的 ...

  3. Python程序中的线程操作-创建多线程

    目录 一.python线程模块的选择 二.threading模块 三.通过threading.Thread类创建线程 3.1 创建线程的方式一 3.2 创建线程的方式二 四.多线程与多进程 4.1 p ...

  4. python——线程与多线程进阶

    之前我们已经学会如何在代码块中创建新的线程去执行我们要同步执行的多个任务,但是线程的世界远不止如此.接下来,我们要介绍的是整个threading模块.threading基于Java的线程模型设计.锁( ...

  5. Python 线程、进程和协程

    python提供了两个模块来实现多线程thread 和threading ,thread 有一些缺点,在threading 得到了弥补,为了不浪费时间,所以我们直接学习threading 就可以了. ...

  6. [python] 线程简介

    参考:http://www.cnblogs.com/aylin/p/5601969.html 我是搬运工,特别感谢张岩林老师! python 线程与进程简介 进程与线程的历史 我们都知道计算机是由硬件 ...

  7. Python 线程(threading) 进程(multiprocessing)

    *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...

  8. python线程同步原语--源码阅读

    前面两篇文章,写了python线程同步原语的基本应用.下面这篇文章主要是通过阅读源码来了解这几个类的内部原理和是怎么协同一起工作来实现python多线程的. 相关文章链接:python同步原语--线程 ...

  9. Python 线程同步变量,同步条件,列队

    条件变量同步 有一类线程需要满足条件之后才能够继续执行,Python提供了threading.Condition 对象用于条件变量线程的支持,它除了能提供RLock()或Lock()的方法外,还提供了 ...

随机推荐

  1. css去掉点击连接时所产生的虚线边框技巧兼容符合w3c标准的浏览器

    解决方法: 1.在css中加上outline:none; 代码如下: a.fontnav { text-align:left;color:#555; text-decoration:none; out ...

  2. async-http

    android-async-http开源框架可以是我们轻松的获取网络数据或者向服务器发送数据,使用起来也很简单,下面做简单介绍,具体详细使用看官网:https://github.com/loopj/a ...

  3. 2018多校第三场 hdu6331 M :Walking Plan

    题目链接 hdu6331 自我吐槽,这场多校大失败,开局签到因输入输出格式写错,wa了3发.队友C题wa了1个小时,还硬说自己写的没错,结果我随便造了个小数据,他都没跑对.然后跑对了后又进入了无限的卡 ...

  4. JSP中include指令和include动作浅析

    一. JSP工作原理 JSP文件是一种Servlet,其工作方式是先部署源代码后编译为.class文件.JSP会在客户端第一次请求JSP文件时被编译成Servlet,由Servlet处理客户端的请求. ...

  5. Android Handler使用

    1. 介绍 Handler允许向关联线程的消息队列(MessageQueue)发送消息(Message)和可执行对象(Runnable).每个Handler实例都与某个线程(即创建该Handler的线 ...

  6. C 语言中char* 和const char*的区别

    const char *p = "123"; p[1] = '3'; // 会报错p = "456"; // 不会报错 const char * 只是说指针指向 ...

  7. http请求分析

    一个Http请求一般始于如下几种方式: 1.在浏览器中输入一个URL地址 2.网页中的一个超链接 3.Response.Redirect("http://www.sohu.com" ...

  8. 解决:java.lang.ArrayIndexOutOfBoundsException: 160 at com.alibaba.fastjson.serializer.SerializeWriter.writeStringWithDoubleQuote(SerializeWriter.java:868)

    今天线上遇到一个问题,从hbase里读取出来的数据在转换json后输出时出现异常: java.lang.ArrayIndexOutOfBoundsException: 160 at com.aliba ...

  9. Python的程序结构[1] -> 方法/Method[3] -> 魔术方法 __getattr__ 与代理模式

    __getattr__ 方法 __getattr__ 方法当对象调用内部属性(包括方法等)且未找到对应属性的时候会调用的特殊方法.利用这一特性,可是对函数实现一个代理模式. __getattr__方法 ...

  10. Git从入门到速成

    什么是Git Git是Linux发明者Linus开发的一款新时代的版本控制系统,那什么是版本控制系统呢?怎么理解?网上一大堆详细的介绍,但是大多枯燥乏味,对于新手也很难理解,这里我只举几个例子. 熟悉 ...