1. 线程的创建与运行

#!/usr/bin/env python
# _*_ coding:UTF-8 _*_

from threading import Thread

def foo(param1, param2):
    print "{0}{1}".format(param1, param2)

if __name__ == "__main__":

    print "main thread running"

    thread = Thread(target=foo, args=(123, "abc"))

    print "before new thread running"
    thread.start()
    print "after new thread running"

结果:

/Users/liudaoqiang/PycharmProjects/numpy/venv/bin/python /Users/liudaoqiang/Project/python_project/day23/thread_test.py
main thread running
before new thread running
123abcafter new thread running

Process finished with exit code 0

2.线程常用API

thread.getName()  获取线程的名称,子线程的名称默认为Thread-n

thread.setName(name)  设置线程的名称

thread.isDaemon()  是否为守护线程,是守护线程则主线程结束,子线程结束;子线程不是守护线程则主线程等待子线程结束后才结束

thread.setDaemon(bool)  设置是否为守护线程

thread.start()

thread.run()

thread.join(timeout)

#!/usr/bin/env python
# _*_ coding:UTF-8 _*_

from threading import Thread
import time

def bar():
    for item in range(100):
        print item
        time.sleep(1)

if __name__ == "__main__":

    print "main thread running"

    thread = Thread(target=bar, args=())
    thread.setDaemon(True)
    print "before %s running" % thread.getName()
    thread.start()
    print "after %s running" % thread.getName()

    time.sleep(5)

结果:

/Users/liudaoqiang/PycharmProjects/numpy/venv/bin/python /Users/liudaoqiang/Project/python_project/day23/thread_test.py
main thread running
before Thread-1 running
after Thread-1 running
0
1
2
3
4

Process finished with exit code 0

3.join()的使用

#!/usr/bin/env python
# _*_ coding:UTF-8 _*_

from threading import Thread
import time

def bar():
    for item in range(100):
        print item
        time.sleep(1)

if __name__ == "__main__":

    print "main thread running"

    thread = Thread(target=bar, args=())
    thread.setDaemon(True)
    print "before %s running" % thread.getName()
    thread.start()
    thread.join(10)
    print "after %s running" % thread.getName()

    time.sleep(5)

结果:

/Users/liudaoqiang/PycharmProjects/numpy/venv/bin/python /Users/liudaoqiang/Project/python_project/day23/thread_test.py
main thread running
before Thread-1 running
0
1
2
3
4
5
6
7
8
9
after Thread-1 running
10
11
12
13
14

Process finished with exit code 0

注意:

(1)thread.join(timeout) 表示主线程等待子线程运行timeout后,主线程再运行

4.自定义线程类

day23

  __init__.py

  mythread.py

  mythread_test.py

mythread.py

#!/usr/bin/env python
# _*_ coding:UTF-8 _*_

from threading import Thread

class MyThread(Thread):

    def run(self, ):
        print self.getName() + " is running"
        Thread.run(self)

mythread_test.py

#/usr/bin/env python
# _*_ coding:UTF-8 _*_

from day23 import mythread

def foo(param):
    print "Thread running with %s" % param

if __name__ == "__main__":

    thread = mythread.MyThread(target=foo, args=("abc", ))
    thread.start()

结果:

/Users/liudaoqiang/PycharmProjects/numpy/venv/bin/python /Users/liudaoqiang/Project/python_project/day23/mythread_test.py
Thread-1 is running
Thread running with abc

Process finished with exit code 0

注意:

(1)自定义线程类需要继承threading.Thread类并实现run(),在run()中调用父类的run()

(2)使用自定义的类需要导入,导入和使用为:

from package import module

mythread = module.MyThread()

5.生产者-消费者模型

#!/usr/bin/env python
# _*_ coding:UTF-8 _*_

from threading import Thread
from Queue import Queue
import time

class Producer(Thread):

    def __init__(self, name, queue):
        self.__name = name
        self.__queue = queue
        super(Producer, self).__init__()

    def run(self):
        while True:
            if self.__queue.qsize() <= 10:
                self.__queue.put("包子")
                print "%s 生产了一个包子" % (self.__name)
            else:
                time.sleep(1)
        super(Producer,self).run()

class Consumer(Thread):

    def __init__(self, name, queue):
        self.__name = name
        self.__queue = queue
        super(Consumer,self).__init__()

    def run(self):
        while True:
            if not self.__queue.empty():
                self.__queue.get()
                print "%s 消费了一个包子" % (self.__name)
        super(Consumer,self).run()

if __name__ == "__main__":

    queue = Queue(maxsize=200)

    for item in range(3):
        name = "producer %d" % item
        producer = Producer(name, queue)
        producer.start()

    for item in range(100):
        name = "consumer %d" % item
        consumer = Consumer(name, queue)
        consumer.start()

结果:

producer 1 生产了一个包子
consumer 42 消费了一个包子producer 1 生产了一个包子
consumer 42 消费了一个包子

producer 1 生产了一个包子consumer 42 消费了一个包子
producer 1 生产了一个包子 

consumer 99 消费了一个包子producer 1 生产了一个包子
producer 1 生产了一个包子

consumer 94 消费了一个包子
 producer 1 生产了一个包子

6.线程安全锁

#!/usr/bin/env python
# _*_ coding:UTF-8 _*_

import threading
import time

num = 0

def run():
    lock.acquire()
    global num
    num += 1
    lock.release()
    time.sleep(0.01)
    print "%s runing: num is %d" % (thread.getName(), num)

if __name__ == "__main__":

    lock = threading.Lock()

    for item in range(2000):
        thread = threading.Thread(target=run, args=())
        thread.setDaemon(False)
        thread.start()

部分结果:

 Thread-1670 runing: num is 1669
Thread-1671 runing: num is 1669
Thread-1674 runing: num is 1674Thread-1674 runing: num is 1674
 Thread-1674 runing: num is 1674

Thread-1681 runing: num is 1680
Thread-1681 runing: num is 1681
Thread-1685 runing: num is 1684
Thread-1685 runing: num is 1684
Thread-1686 runing: num is 1685
Thread-1687 runing: num is 1685
Thread-1697 runing: num is 1696Thread-1697 runing: num is 1696

Thread-1697 runing: num is 1697Thread-1698 runing: num is 1697

注意:

(1)一个线程没有没有进行sleep,则执行100条指令

(2)线程之间是共享内存资源的,为了线程的安全,需要增加线程锁

(3)双重加锁需要使用lock = threading.RLock()

其他锁:

#!/usr/bin/env python
# _*_ coding:UTF-8 _*_

import threading
import time

num = 0

def run():
    lock.acquire()
    global num
    num += 1
    lock.release()
    time.sleep(0.01)
    print "%s runing: num is %d" % (thread.getName(), num)

if __name__ == "__main__":
    #这时普通锁
    lock = threading.Lock()
    #这是双重锁
    lock = threading.RLock()
    #这时多个线程共享锁
    lock = threading.BoundedSemaphore(4)

    for item in range(2000):
        thread = threading.Thread(target=run, args=())
        thread.setDaemon(False)
        thread.start()

7.生产者-消费者模型的通信事件

#!/usr/bin/env python
# _*_ coding:UTF-8 _*_

import threading
import time

def producer():
    print "生产者:正在等待消费者到来..."
    # 生产者在这里等待,等待消费者将标识位设置位True
    event.wait()
    # 生产者开始工作后,要将标识为清空,即设置位False,让消费者处于等待状态
    event.clear()
    print "生产者:开始生产包子"
    time.sleep(5)
    print "生产者:包子生产完成"
    # 生产完成,将标识位设置位True,让消费者不处于等待状态
    event.set()

def consumer():
    print "消费者:还未到来..."
    time.sleep(3)
    print "消费者:来了..."
    # 将标识位设置位True,让消费者开始工作
    event.set()
    print "消费者:我要包子"
    # 这里需要延时
    time.sleep(1)
    # 通过判断生产者是否将标识位设置位True
    while True:
        if event.isSet():
            print "消费者:谢谢"
            break
        else:
            print "消费者:好了吗"
            time.sleep(1)

if __name__ == "__main__":

    #定义生产者和消费者的通信事件
    event = threading.Event()

    producer = threading.Thread(target=producer, args=())
    producer.start()

    consumer = threading.Thread(target=consumer, args=())
    consumer.start()

结果:

/Users/liudaoqiang/PycharmProjects/numpy/venv/bin/python /Users/liudaoqiang/Project/python_project/day23/thread_set_test.py
生产者:正在等待消费者到来...
消费者:还未到来...
消费者:来了...
消费者:我要包子生产者:开始生产包子

消费者:好了吗
消费者:好了吗
消费者:好了吗
消费者:好了吗
生产者:包子生产完成
消费者:谢谢

Process finished with exit code 0

注意:

(1)该通信事件的目的是生产者可以控制消费者是否等待;消费者也可以控制生产者是否等待

老男孩python学习自修第二十三天【多线程】的更多相关文章

  1. 老男孩python学习自修第二十四天【多进程】

    1. 体验多进程的运行速度 #!/usr/bin/env python # _*_ coding:UTF-8 _*_ from multiprocessing import Pool import t ...

  2. 老男孩 python学习自修第二十二天【文件上传与下载】

    1.使用socket实现文件上传 server.py #!/usr/bin/env python # _*_ coding:UTF-8 _*_ import os import SocketServe ...

  3. 老男孩python学习自修第十三天【md5加密】

    示例代码如下: hashlib_test.py #!/usr/bin/env python # _*_ coding:UTF-8 _*_ import hashlib def genPasswd(na ...

  4. 老男孩python学习自修【第二天】字符串用法

    实时处理增量日志最佳实践 主要使用f.seek()和f.tell()实现 字符串处理函数: s.find(substr, start, end) 查找子字符串,找不到则返回-1,找到则返回对应的索引 ...

  5. Python学习笔记第二十三周(Flask架构)

    目录: 一.变量引用 内容: 备注:PyCharm小技巧,comm+alt+l  自动修改格式,comm+alt+return  向上添加新行 一.变量引用 1.url生成 from flask im ...

  6. 老男孩python学习自修第十六天【常用模块之sys和os】

    例子: sys.argv 命令行参数List,第一个元素是程序本身路径 sys.exit(n) 退出程序,正常退出时exit(0) sys.version 获取Python解释程序的版本信息 sys. ...

  7. 老男孩python学习自修第十九天【异常处理】

    1.常见的错误 TypeError 类型错误 NameError 没有该变量 ValueError 不期望的值 AttributeError 没有该属性 UnboundLocalError 没有该局部 ...

  8. 老男孩python学习自修第十八天【面向对象】

    1.类与对象(构造方法与实例化) #!/usr/bin/env python # _*_ coding:UTF-8 _*_ class Province: def __init__(self, nam ...

  9. 老男孩python学习自修第十七天【装饰器】

    装饰器:在某个方法执行前后去执行其他新定义的行为 例如: #!/usr/bin/env python # _*_ coding:UTF-8 _*_ def before_say_hello(): pr ...

随机推荐

  1. ssm框架的整合搭建(三)

    mybatis逆向工程工具类的使用---mybatis  generator 项目结构 配置文件 <?xml version="1.0" encoding="UTF ...

  2. Python:Day07 作业

    三级菜单: 自己做的代码: china = { '江苏':{ '南京':{ '江宁':{}, '白下':{}, '栖霞':{}, '江淮':{}, '浦口':{} }, '宿迁':{ '宿城区':{} ...

  3. 【angularjs】使用angularjs模拟淘宝首页-淘宝头条滚动效果

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  4. angularjs处理/n转<br/>时候 <br/>不会解析的问题

    $scope.name=$sce.trustAsHtml($scope.name); <p ng-bind-html="name"></p>  

  5. ActiveMQ的作用总结(应用场景及优势)

    业务场景说明: 消息队列在大型电子商务类网站,如京东.淘宝.去哪儿等网站有着深入的应用, 队列的主要作用是消除高并发访问高峰,加快网站的响应速度. 在不使用消息队列的情况下,用户的请求数据直接写入数据 ...

  6. hyperledge环境安装

    1.安装环境 1)本机安装 前提是已经安装好了docker\docker-compose\go,相应的内容可见 docker-1-环境安装及例子实践 docker官方文档学习-1-Docker for ...

  7. python __call__方法的使用

    介绍一下python __call__ 方法的使用 代码如下: #!/usr/bin/env python # -*- coding: utf- -*- ''' __call__方法 普通的类定义的方 ...

  8. c# 设置IE浏览器版本运行程序-设置webBrowser对应的IE内核版本来运行

    //通常情况下,我们直接调用C#的webBrowser控件,默认的浏览器内核是IE7.  那么如何修改控件调用的默认浏览器版本呢?using System; using System.Collecti ...

  9. odoo 11 配置nginx反向代理

    第一步 安装nginx 和 certbot    具体步骤可以参考这篇文章的第6,7步. 第二步 配置nginx映射到odoo网站的文件,主要有2个,文件中的cloudapp.top是我们自己的域名, ...

  10. UI 前端参考

    :http://amazeui.org/ :http://www.dcloud.io/index.html :https://weui.io/ :http://m.sui.taobao.org/get ...