调用方式

python的线程调用有两种方式。一种是直接调用,一种是继承式调用

直接调用

import threading,time#方法一
def run(n):print(n)time.sleep(2)
t1 = threading.Thread(target=run,args=("t1",))
t2 = threading.Thread(target=run,args=("t2",))
t1.start()
t2.start()

使用类的方法调用

#方法二(使用类的方法)
import threading,time
class MyThread(threading.Thread):def __init__(self,n):super(MyThread,self).__init__()self.n = ndef run(self):     #函数名必须为runprint(self.n)time.sleep(2)t1 = MyThread(1)
t2 = MyThread(2)t1.start()
t2.start()

join和Daemon

join()等待线程结束后再往后继续运行

Daemon()守护线程

使用setDaemon(True)那么主线程不会等待子线程结束才结束,主线程结束后子线程也会直接结束,必须要在start之前设置否则会报错

python中默认为setDaemon(False),主线程结束了子线程依然会执行直到完毕。

join例子:

import threading,time
class MyThread(threading.Thread):def __init__(self,n):super(MyThread,self).__init__()self.n = ndef run(self):     #函数名必须为runprint(self.n)time.sleep(2)print('end')t1 = MyThread('t1')
t2 = MyThread('t2')
t1.start()
t1.join()
t2.start()
t2.join()

结果

setDaemon()例子

import threading,time
class MyThread(threading.Thread):def __init__(self,n):super(MyThread,self).__init__()self.n = ndef run(self):     #函数名必须为runprint(self.n)time.sleep(2)print('end')t1 = MyThread('t1')
t2 = MyThread('t2')
t1.setDaemon(True)
t2.setDaemon(True)
t1.start()
t2.start()

结果

线程锁

子线程可以共享父线程的内存空间,当存在多个子线程需要同时修改一个数据的时候就可能出现问题
假设两个子线程执行的操作都是num+1,由于线程是同时执行的,第一个子线程先取num = 1 ,第二个线程有取出num依然为1,线程一结束后num更改为2,随之线程二结束num依然被改为2,就与我们的目标出现冲突,这个时候就需要用到线程锁了,当线程一访问num的时候线程二是无法访问num的,线程一结束后释放num线程二才能访问num,这就使得num的结果不会产生冲突了。
#线程锁示例
import threadingnum = 0
t_objs = []
lock = threading.Lock()def run():lock.acquire()  #加锁global num      #声明全局变量num += 1        #执行加一操作lock.release()  #释放锁for i in range(500):t = threading.Thread(target=run)t.start()t_objs.append(t)for t in t_objs:    #等待所有线程结束t.join()print(num)

递归锁则是在一个锁里面又嵌套另外一个线程锁

#递归锁
import threadingdef run1():lock.acquire()global numnum += 1lock.release()return numdef run2():lock.acquire()global num2num2 += 1lock.release()return num2def run3():lock.acquire()res = run1()res2 = run2()lock.release()print(res, res2)if __name__ == '__main__':num, num2 = 0, 0lock = threading.RLock()for i in range(10):t = threading.Thread(target=run3)t.start()

结果

信号量(Semaphore)

线程锁每次只允许一个线程操作数据,Semaphore则可同时允许多个线程操作,当达到允许的最大值的时候后面的则需要等待,前面的线程执行完毕后才可执行,因此操作同一个数据的时候依然有可能出错
#信号量import threading,timedef run(num):semaphore.acquire()time.sleep(1)print(num)semaphore.release()semaphore = threading.BoundedSemaphore(3) #最多运行三个线程
for i in range(10):t = threading.Thread(target=run,args=(i,))t.start()

事件(Event)

Event默认内置了一个标志,初始值为False
event总共就四中方法:set()、clear()、wait()、is_set()
set()设置标志位为True
clear()设置标志位为False
wait()等待标志位设为True
is_set()判断标志位是否被设为True
已红绿灯为例说明,首先写出交通灯,event.clear()相当于红灯,event.set()相当于绿灯,红灯为5秒绿灯也为5秒,用count来计数,当count超过10的时候重置count,这样红绿灯就能以5秒为间隔循环运行
import time,threadingevent = threading.Event()def light():count = 0while True:if count >= 5 and count < 10:event.clear()     #相当于红灯了print("red light please wait...")elif count > 10 :event.set()       #相当于绿灯count = 0        else:print("go go go ...")time.sleep(1)count += 1

再来写car

def car():while True:if event.is_set():  #判断event是否被set,相当于检测是否为绿灯print('run...')time.sleep(1)else:print('waiting for green light..')event.wait()print('green light is on go...')

运行

l = threading.Thread(target=light)
c = threading.Thread(target=car)
l.start()
c.start()

最终的结果

转载于:https://www.cnblogs.com/FanMLei/p/10501032.html

Python基础---线程相关推荐

  1. Python基础--线程

    在Python3中可以通过两种方式来创建线程 1.通过threading.Thread直接在线程中运行函数 2.通过继承threadting.Thread类来创建线程 用threading.Threa ...

  2. python网络编程基础(线程与进程、并行与并发、同步与异步、阻塞与非阻塞、CPU密集型与IO密集型)...

    python网络编程基础(线程与进程.并行与并发.同步与异步.阻塞与非阻塞.CPU密集型与IO密集型) 目录 线程与进程并行与并发同步与异步阻塞与非阻塞CPU密集型与IO密集型 线程与进程 进程 前言 ...

  3. Python基础教程:线程操作(oncurrent模块)详解

    进程是cpu资源分配的最小单元,一个进程中可以有多个线程. 线程是cpu计算的最小单元. 对于Python来说他的进程和线程和其他语言有差异,是有GIL锁. GIL锁 GIL锁保证一个进程中同一时刻只 ...

  4. Python基础之线程(Thread)

    进程 之前我们已经了解了操作系统中进程的概念,程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程.程序和进程的区别就在于:程序是指令的集合,它是进程运行 ...

  5. Python进阶并发基础--线程,全局解释器锁GIL由来,如何更好的利用Python线程,

    全局解释器锁GIL 官方对于线程的介绍: 在 CPython 中,由于存在全局解释器锁,同一时刻只有一个线程可以执行 Python代码(虽然某些性能导向的库可能会去除此限制).如果你想让你的应用更好地 ...

  6. python删除线程,python线程基础

    一 基本概念 1 并行和并发 1 并行,parallel 同时做某些事,可以互不干扰的同一时刻做几件事 如高速公路上的车道,同一时刻,可以有多个互不干扰的车运行 在同一时刻,每条车道上可能同时有车辆在 ...

  7. 8.Python基础学习笔记day8-正则表达式、网络编程、进程与线程

    8.Python基础学习笔记day8-正则表达式.网络编程.进程与线程 一.正则表达式 ''' 1. [1,2,3,4]中任意取3个元素排列: A43 = 4x3x2 = 24itertools.pe ...

  8. Python基础 - 第九天 - paramiko模块、进程、线程

    本篇内容: 1.paramiko模块使用 2.进程.线程简介 3.python调用线程的方法 4.join - 等待线程执行 5.守护线程 6.GIL - 全局解释器锁 7.互斥锁 8.信号量 9.事 ...

  9. python基础主要内容_python基础—python的介绍

    编译器是把源程序的每一条语句都编译成机器语言,并保存成二进制文件,这样运行时计算机可以直接以机器语言来运行此程序,速度很快; 而解释器则是只在执行程序时,才一条一条的解释成机器语言给计算机来执行,所以 ...

最新文章

  1. mysql协议解析器_mysql协议解析
  2. 高效进行 Oracle 日常巡检——数据库基本情况检查
  3. Sklearn-train_test_split随机划分训练集和测试集
  4. Linux从零开始(三、命令图解)
  5. element更改表格表头、行、指定单元格样式
  6. couchbase_Couchbase 101:从Java应用程序创建视图(MapReduce)
  7. mysql中文注入_SQL注入之Mysql报错注入
  8. Oracle触发器之表新增/修改的触发操作
  9. 打开office 文档慢的小技巧1 更改默认打印机
  10. oracle执行计划没有执行索引,oracle理解执行计划之索引相关
  11. 不同编码页引用同一个css文件
  12. 求解函数最值的几种算法,梯度下降法python实现
  13. 微信小程序搭建怎么做?流程是怎么样?【小程序搭建】
  14. opencv实战项目:基于opencv的车牌号码识别
  15. CRUSH算法 - 可控、可伸缩、分布式地归置多副本数据
  16. 数组下标越界可能出现的问题
  17. Amazon EKS 使用 EFS服务
  18. Ubuntu虚拟机扩展磁盘空间并合并
  19. 雅克比 (Jacobi) 迭代法求线性方程组的解及其代码
  20. asm(” RPT #7 || NOP”)

热门文章

  1. MySQL安装失败出现could not start the service mysql error:0 错误提示
  2. Java基础加强总结(三)——代理(Proxy)
  3. 在博客园添加Lisp(或其它)代码高亮
  4. MySQL第一篇 (linux ubuntu平台 学习《MySQL技术内幕》总结)
  5. web前端环境搭建以及vue-cli搭建启动vue项目
  6. 3、Spring Cloud - Eureka(高可用Eureka Server集群)
  7. 华东师范大学2019年高等代数考研试题
  8. 你不知道的JavaScript·第一部分
  9. 零基础的前端开发初学者应如何系统地学习?
  10. Python——阶段总结(一)