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. java的大端小端和c#如何对应

    当前的存储器,多以byte为访问的最小单元,当一个逻辑上的地址必须分割为物理上的若干单元时就存在了先放谁后放谁的问题,于是端(endian)的问题应运而生了,对于不同的存储方法,就有大端(big-en ...

  2. UI-1-UI入门

    课程要点: 创建一个iOS工程 AppDelegate类 UIKit框架以及UIWindow 在window上添加第一个试图UIView NSTimer(定时器) 创建一个iOS工程 PS:接下来简单 ...

  3. Snowflake Snow Snowflakes - poj 3349 (hash函数)

    判断n朵雪花中,是否有完全一样的雪花.简单的hash,将雪花的六个边的权值加起来,记为sum,将sum相等的雪花归为一类,再在这里面根据题意找完全相同的,判断顺时针或者逆时针的所有角是否一模一样. # ...

  4. CentOS 7 换yum源

    备份原来的源 sudo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bk 下载阿里源 $ cd /et ...

  5. 第一百八十七节,jQuery,知问前端--cookie 插件,注册成功后生成cookie,显示登录状态

    jQuery,知问前端--cookie 插件 学习要点: 1.使用 cookie 插件 2.注册直接登录 Cookie 是网站用来在客户端保存识别用户的一种小文件.一般来用库可以保存用户登 录信息.购 ...

  6. codeforces(559C)--C. Gerald and Giant Chess(组合数学)

    C. Gerald and Giant Chess time limit per test 2 seconds memory limit per test 256 megabytes input st ...

  7. Editor编辑器的一些用法

    共有两个脚本,一个是有关Inspector面板的,一个是window的 using UnityEngine; using System.Collections; using UnityEditor; ...

  8. Classification week6: precision & recall 笔记

    华盛顿大学 machine learning :classification  笔记 第6周 precision & recall 1.accuracy 局限性 我们习惯用 accuracy ...

  9. Uva1025 A Spy in the Metro

    #include <iostream> #include <cstring> #include <cstdio> using namespace std; ]; ] ...

  10. Lumen migration(数据库协同)

    建立迁移文件/新建表文件 php artisan make:migration create_users_table 添加字段 php artisan make:migration add_colum ...