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. c#序列化和反序列化list

    List<UserData> lstStuModel = new List<UserData>() { new UserData(){Name="001", ...

  2. iOS- 详解文本属性Attributes(转)

    iOS- 详解文本属性Attributes 1.NSKernAttributeName: @10 调整字句 kerning 字句调整 2.NSFontAttributeName : [UIFont s ...

  3. Tomcat启动报错:SERVER: Error ListenerStart 排查过程记录

    报错的Tomcat截图:   要排查此问题,首先需要调整tomcat的日志级别,调整成通过log4j来记录日志的方式,具体的调整方式: http://tomcat.apache.org/tomcat- ...

  4. Java并发编程(十二)线程安全性的委托

    在组合对象中如果每个组件都已经是线程安全的,是否需要再加一个额外的"线程安全层",需要视情况而定. final可以修饰未复制的属性,只要在静态代码块或者构造函数中赋值了即可. 独立 ...

  5. CI框架基本配置/教你学习CI框架codelgniter

    CI框架现在中国可以说还是不成熟,不像thinkphp那样有那么多的中文手册,在国内,很多国人英语都很烂,CI现在教程还是不多.大家心里都存在这严重想法 CI 框架现在中国可以说还是不成熟,不像thi ...

  6. Oracle基础学习登陆SQLPLUS(一)

    SQLPLUS是ORACLE公司开发的非常简洁的管理工具,SQLPLUS是最好的,最核心的ORACLE管理工具.SQLPLUS简洁而高效,舍弃浮华,反璞归真.使用sqlplus,进入sqlplus并进 ...

  7. 【Mac + Appium】之运行报错:[UiAutomator] UiAutomator exited unexpectedly with code 0, signal null

    产生下面的原因是因为:与uiautomator2的weditor冲突,两者不能同时使用. 有时打开appium时会报错: [UiAutomator] UiAutomator exited unexpe ...

  8. OpenGL ES andoid学习————1

    package com.xhm.getaccount; import javax.microedition.khronos.egl.EGLConfig; import javax.microediti ...

  9. python3 - property的使用

    传统的绑定属性值,会把属性暴露出去,而且无法检查参数是否合法,如下: class Test(object): def  __int__(self,age): self.age = age 为了检查参数 ...

  10. SQL.Cookbook 读书笔记5 元数据查询

    第五章 元数据查询 查询数据库本身信息 表结构 索引等 5.1 查询test库下的所有表信息 MYSQL SELECT * from information_schema.`TABLES` WHERE ...