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. gulp安装使用

    1. 安装nodeJs   2. 全局安装gulp: npm install gulp -g   3. 在cmd切换至项目文件夹下 npm init,创建package.json文件(JSON文件内不 ...

  2. java - day13 - ImplementDemo

    接口实现.继承等关系的运用案例P.S: 强制转换,看引用变量指向的对象与目标数据间的关系.可运用 "引用变量 instanceof 目标数据" 来判断是否可用强转 package ...

  3. mvn test中文乱码处理

    mvn test执行测试的时候调用的实际是maven-surefire-plugin插件因为mvn启动时会新建一个jvm进程,默认没有指定编码所以中文乱码了.启动时`<argLine>-D ...

  4. 360 网络攻防 hackgame 解题报告(通关)

    地址:http://challenge.onebox.so.com/ 1.referrer or host 2.js decode 3.urldecode, ASCII 4.JFIF * 2 5.go ...

  5. AD使用技巧

    1. 效果显示 3 显示3D效果,2显示2D效果. 2.  阻焊塞孔 双击过孔显示属性  solder Mask Expansions Force complete tenting on top Fo ...

  6. HashMap? ConcurrentHashMap?

    前言 Map 这样的 Key Value 在软件开发中是非常经典的结构,常用于在内存中存放数据. 本篇主要想讨论 ConcurrentHashMap 这样一个并发容器,在正式开始之前我觉得有必要谈谈 ...

  7. 在linux下使用curl

    使用curl从 ftp下载文件 curl ftp://192.168.31.164/lrzsz-0.12.20.tar.gz --user root:123456 -o lrzsz-0.12.20.t ...

  8. linux tableau server 连接 presto

    记录一下这个弄个好久的难题 linux tableau server 版本  tableau-server-2018-2-0.x86_64.rpm 安装过程 我参照了这儿仁兄   http://ju. ...

  9. Cocos2d-x Lua中生命周期函数

    场景(Scene)以及所有节点(Node)的生命周期事件如下:enter.进入场景时候触发.enterTransitionFinish.进入场景而且过渡动画结束时候触发.exit.退出场景时候触发 . ...

  10. oracelp---随意 记录(nvl)

    1.Oracle的Nvl函数 nvl( ) 函数 从两个表达式返回一个非null 值. 语法 NVL(eExpression1, eExpression2) 参数 eExpression1, eExp ...