0.什么是线程

1. 多线程模块

2. 创建线程的方法

3. join()方法

4.isAlive()方法

5. name属性和daemon属性

6.线程的同步---锁

7.线程的同步---Event对象

8.线程的同步---Condition条件变量

1. 多线程模块 

python3对多线程支持的是 threading 模块,应用这个模块可以创建多线程程序,并且在多线程间进行同步和通信。在python3 中,可以通过两种方法来创建线程:

第一:通过 threading.Thread 直接在线程中运行函数;第二:通过继承 threading.Thread 类来创建线程

view plain copy

  1. import threading  
  2.   
  3. def threadfun(x,y):         #线程任务函数 threadfun()  
  4.     for i in range(x,y):  
  5.         print(i)  
  6.   
  7. ta = threading.Thread(target=threadfun,args=(1,6))      #创建一个线程ta,执行 threadfun()  
  8. tb = threading.Thread(target=threadfun,args=(10,15))    #创建一个线程tb,执行threadfun()  
  9. ta.start()          #调用start(),运行线程  
  10. tb.start()          #调用start(),运行线程  
  11. '''''打印:1 2 3 4 5 10 11 12 13 14'''  



2.通过继承 thread.Thread 类 来创建线程 

这种方法只需要重载 threading.Thread 类的 run 方法,然后调用 start()开启线程就可以了

  1. import threading
  2. class mythread(threading.Thread):
  3. def run(self):
  4. for i in range(1,5):
  5. print(i)
  6. ma = mythread();
  7. mb = mythread();
  8. ma.start()
  9. mb.start()

view plain copy

  1. import threading  
  2. import time  
  3. class mythread(threading.Thread):  
  4.     def run(self):  
  5.         self.i = 1  
  6.         print('%d'%(self.i))  
  7.         self.i = self.i+1  
  8.         time.sleep(1)           #睡眠一秒  
  9.         print('%d'%(self.i))  
  10.         time.sleep(1)  
  11.   
  12. if __name__ == '__main__':  
  13.     ta = mythread()     #实例化线程  
  14.     ta.start()          #开启ta线程  
  15.     ta.join()           #主线程等待 ta线程结束才继续执行  
  16.     print('main thread over')  

view plain copy

  1. import threading  
  2. import time  
  3. class mythread(threading.Thread):  
  4.     def run(self):  
  5.        time.sleep(2)  
  6.   
  7. if __name__ == '__main__':  
  8.     ta = mythread()     #实例化线程  
  9.     print(ta.isAlive())   #打印False,因为未执行 start()来使ta线程运行  
  10.     ta.start()  
  11.     print(ta.isAlive())   #打印Ture,因为ta线程运行了  
  12.     time.sleep(3)  
  13.     print(ta.isAlive())   #打印False,因为ta线程已经结束了  

5. name属性和daemon属性

1.name属性表示线程的线程名 默认是 Thread-x  x是序号,由1开始,第一个创建的线程名字就是 Thread-1

  1. import threading
  2. import time
  3. class mythread(threading.Thread):
  4. def run(self):
  5. pass
  6. if __name__ == '__main__':
  7. ta = mythread()     #实例化线程
  8. ta.name = 'thread-ta'
  9. tb = mythread()
  10. tb.start()
  11. ta.start()
  12. print(ta.name)  #打印 thread-ta
  13. print(tb.name)  #打印 Thread-2

view plain copy

  1. import threading
  2. import time
  3. class mythread(threading.Thread):
  4. def run(self):
  5. time.sleep(2)
  6. print('my thread over')
  7. def main():
  8. ta = mythread()
  9. ta.daemon = True
  10. ta.start()
  11. print('main thread over')
  12. if __name__ == '__main__':
  13. main()
  14. #打印结果 :main thread over   然后马上结束程序


6.线程的同步---锁
当一个进程拥有多个线程之后,如果他们各做各的任务互没有关系还行,但既然属于同一个进程,他们之间总是具有一定关系的。比如多个线程都要对某个数据进行修改,则可能会出现不可预料的结果。为保证操作正确,就需要引入锁来进行线程间的同步。

python3 中的 threading 模块提供了
RLock锁(可重入锁)。对于某一时间只能让一个线程操作的语句放到 RLock的acquire 方法 和 release方法之间。即
acquire()方法相当于给RLock 锁  上锁,而 release() 相当于解锁。

  1. import threading
  2. import time
  3. class mythread(threading.Thread):
  4. def run(self):
  5. global x            #声明一个全局变量
  6. lock.acquire()      #上锁,acquire()和release()之间的语句一次只能有一个线程进入,其余线程在acquire()处等待
  7. x += 10
  8. print('%s:%d'%(self.name,x))
  9. lock.release()      #解锁
  10. x = 0
  11. lock = threading.RLock()    #创建 可重入锁
  12. def main():
  13. l = []
  14. for i in range(5):
  15. l.append(mythread())    #创建 5 个线程,并把他们放到一个列表中
  16. for i in l:
  17. i.start()               #开启列表中的所有线程
  18. if __name__ =='__main__':
  19. main()

打印结果:

Thread-1:10
Thread-2:20
Thread-3:30
Thread-4:40
Thread-5:50


7.线程的同步---Event对象
Event对象存在于 threading 模块中。Event 实例管理着 一个内部标志,通过 set() 方法来将该标志设置成 True,使用
clear() 方法将该标志重置成 False

wait() 方法会使当前线程阻塞直到标志被设置成 True,wait()可以选择给他一个参数,代表时间,代表阻塞多长时间,若不设置就是阻塞直到标志被设置为True

isSet()方法  :能判断标志位是否被设置为True

  1. import threading
  2. import time
  3. class Mon(threading.Thread):
  4. def run(self):
  5. Dinner.clear()
  6. print('Cooking dinner')
  7. time.sleep(3)
  8. Dinner.set()    #标志设置为True
  9. print(self.name,':dinner is OK!')
  10. class Son(threading.Thread):
  11. def run(self):
  12. while True:
  13. if Dinner.isSet():  #判断标志位是否被设置为True
  14. break
  15. else:
  16. print('dinner isnot ready!')
  17. Dinner.wait(1)
  18. print(self.name,':Eating Dinner')
  19. def main():
  20. mon = Mon()
  21. son = Son()
  22. mon.name = 'Mon'
  23. son.name = 'Son'
  24. mon.start()
  25. son.start()
  26. if __name__ == '__main__':
  27. Dinner = threading.Event()
  28. main()
  29. '''''
  30. Cooking dinner
  31. dinner isnot ready!
  32. dinner isnot ready!
  33. dinner isnot ready!
  34. Mon :dinner is OK!
  35. Son :Eating Dinner
  36. '''

注意,这里的wait()跟上面Event提到的wait()不是同一样东西

notify()
发出资源可用的信号,唤醒任意一条因 wait()阻塞的进程

notifyAll()
发出资源可用信号,唤醒所有因wait()阻塞的进程

下面给出一个例子,一家蛋糕店:只会做一个蛋糕,卖出后才会再做一个。绝对不会做积累到2个蛋糕。

    1. import threading
    2. import time
    3. class Server(threading.Thread):
    4. def run(self):
    5. global x
    6. while True:
    7. con.acquire()
    8. while x>0:
    9. con.wait()
    10. x += 1
    11. time.sleep(1)
    12. print(self.name,':I make %d cake!'%(x))
    13. con.notifyAll()
    14. con.release()
    15. class Client(threading.Thread):
    16. def run(self):
    17. global x
    18. con.acquire()
    19. while x == 0:
    20. con.wait()
    21. x-=1
    22. print(self.name,'I bought a cake! the rest is %d cake'%(x))
    23. con.notifyAll()
    24. con.release()
    25. def main():
    26. ser = Server()
    27. ser.name = 'Cake Server'
    28. client = []
    29. for i in range(3):
    30. client.append(Client())
    31. ser.start()
    32. for c in client:
    33. c.start()
    34. if __name__ =='__main__':
    35. x = 0
    36. con = threading.Condition()
    37. main()
    38. '''''
    39. 打印结果:
    40. Cake Server :I make 1 cake!
    41. Thread-3 I bought a cake! the rest is 0 cake
    42. Cake Server :I make 1 cake!
    43. Thread-4 I bought a cake! the rest is 0 cake
    44. Cake Server :I make 1 cake!
    45. Thread-2 I bought a cake! the rest is 0 cake
    46. Cake Server :I make 1 cake!
    47. '''

python3 多线程编程的更多相关文章

  1. Python3 多线程编程 - 学习笔记

    线程 什么是线程 特点 线程与进程的关系 Python3中的多线程 全局解释器锁(GIL) GIL是啥? GIL对Python程序有啥影响? 改善GIL产生的问题 Python3关于多线程的模块 多线 ...

  2. Python3 多线程编程(thread、threading模块)

    threading是对thread的封装. 1.开启线程: t=threading.Thread(target=sayhi,args=('hh',)) t.start() 或者先建一个Thread的继 ...

  3. Python3 多线程编程 threading模块

    性能自动化测试除了用jmeter还可以用python threading模块做 一.threading模块定义 Python 2.4中包含的较新的线程模块为线程提供了更强大的高级支持. 线程模块公开线 ...

  4. python --- 基础多线程编程

    在python中进行多线程编程之前必须了解的问题: 1. 什么是线程? 答:线程是程序中一个单一的顺序控制流程.进程内一个相对独立的.可调度的执行单元,是系统独立调度和分派CPU的基本单位指运行中的程 ...

  5. Python中的多线程编程,线程安全与锁(二)

    在我的上篇博文Python中的多线程编程,线程安全与锁(一)中,我们熟悉了多线程编程与线程安全相关重要概念, Threading.Lock实现互斥锁的简单示例,两种死锁(迭代死锁和互相等待死锁)情况及 ...

  6. Python中的多线程编程,线程安全与锁(一)

    1. 多线程编程与线程安全相关重要概念 在我的上篇博文 聊聊Python中的GIL 中,我们熟悉了几个特别重要的概念:GIL,线程,进程, 线程安全,原子操作. 以下是简单回顾,详细介绍请直接看聊聊P ...

  7. Python3 多进程编程 - 学习笔记

    Python3 多进程编程(Multiprocess programming) 为什么使用多进程 具体用法 Python多线程的通信 进程对列Queue 生产者消费者问题 JoinableQueue ...

  8. Web Worker javascript多线程编程(一)

    什么是Web Worker? web worker 是运行在后台的 JavaScript,不占用浏览器自身线程,独立于其他脚本,可以提高应用的总体性能,并且提升用户体验. 一般来说Javascript ...

  9. Web Worker javascript多线程编程(二)

    Web Worker javascript多线程编程(一)中提到有两种Web Worker:专用线程dedicated web worker,以及共享线程shared web worker.不过主要讲 ...

随机推荐

  1. ../lib//libscsdblog.so: undefined reference to `pthread_atfork'

    代码中遇到这个问题,但是在makefile中已经添加了-lpthread. 最后发现问题时,引入库的顺序,把-lpthread放在最后就可以了.

  2. 【原创】菜鸟版Android 笔记2- Activity

    1. Activity介绍 Acitivity在安卓开发中非常重要,他很像Java桌面开发中的JFrame,在MVC模式中属于Controller,一般一个应用程序通常由多个松耦合关系的activit ...

  3. PHPWord使用方法

    官方文档  github地址 一.安装 直接使用composer安装,链接地址 composer require phpoffice/phpword 二.简单使用 require_once 'PhpO ...

  4. 23:LVS客户端配置脚本案例

    [root@web03 scripts]# cat prevent_arp.sh #!/bin/bash lo_ip=$(ip a s lo|grep "10.0.0.1[3]/32&quo ...

  5. gen_server边缘

    我们以Module代表gen_server的callback模块 1, 实现gen_server behaviour的模块会产生一个新的process么? 毫无疑问,太会了!通过调用proc_lib: ...

  6. Scrapy爬虫入门系列4抓取豆瓣Top250电影数据

    豆瓣有些电影页面需要登录才能查看. 目录 [隐藏]  1 创建工程 2 定义Item 3 编写爬虫(Spider) 4 存储数据 5 配置文件 6 艺搜参考 创建工程 scrapy startproj ...

  7. Servlet 点击计数器

    网页点击计数器 很多时候,您可能有兴趣知道网站的某个特定页面上的总点击量.使用 Servlet 来计算这些点击量是非常简单的,因为一个 Servlet 的生命周期是由它运行所在的容器控制的. 以下是实 ...

  8. sql server case when then

    http://blog.csdn.net/wuxiaokaixinguo/article/details/8895187

  9. python3----splitlines

    Python中的splitlines用来分割行.当传入的参数为True时,表示保留换行符 \n.通过下面的例子就很明白了: mulLine = """Hello!!! W ...

  10. DHCP动态主机配置协议

    1.DHCP简述 某组织一旦获得了一个地址,它就可以为本组织内的主机与路由器接口逐个分配IP地址.系统管理通常可以手工配置路由器中的IP地址(静态分配).但这项任务目前通常更多是使用动态主机配置协议( ...