精华内容
下载资源
问答
  • 如果发生事件,在Python唤醒一个线程
    2021-03-06 20:36:22

    我知道已经有人问过这样的问题,所以从某种意义上说,这是一个重复。然而,我看了很多这样的问题,和无数的网站,我仍然不知道如何做这个问题的标题说什么。这就是我想要实现的,更具体地说:

    一个线程t_sensors从传感器中读取值,然后进入睡眠状态refresh_rate秒。这可能需要几个小时,因此在这段时间内,它可以再次收到从传感器读取值的请求。这个请求来自线程t_checker,它检查Firebase数据库中的数据,并根据数据选择是否唤醒t_sensors。在def start_sensors(self):

    # do some stuff...

    # refreshes every refresh_rate secs

    refresh_rate = firebase_root.get('/settings', 'refreshRate')

    condition.wait(refresh_rate)

    def check_for_plants(self):

    while True:

    modded_plants = firebase_root.get('/modifiedPlants', '')

    print(modded_plants)

    for plant, properties in modded_plants.items():

    print properties['status']

    if properties['status'] == 'modified':

    condition.notify()

    print("Notified")

    condition = threading.Condition()

    t_sensors = threading.Thread(target=start_sensors, args=(condition,))

    t_checker = threading.Thread(target=check_for_plants, args=(condition,))

    condition.acquire()

    t_sensors.start()

    t_checker.start()

    我知道我根本没有正确地使用条件,但是我真的不知道应该从哪里开始解决这个问题。我真的非常感谢你的帮助。在

    更多相关内容
  • python线程

    2021-03-06 20:36:02
    python线程真正的多线程吗?对于多核处理器,在同一时间确实可以多个线程独立运行,但在Python中确不是这样的了。原因在于,python虚拟机中引入了GIL这一概念。GIL(Global Interpreter Lock)全局解析器锁是用来...

    python 多线程

    真正的多线程吗?

    对于多核处理器,在同一时间确实可以多个线程独立运行,但在Python中确不是这样的了。原因在于,python虚拟机中引入了GIL这一概念。GIL(Global Interpreter Lock)全局解析器锁是用来解决共享资源访问的互斥问题,导致在python虚拟机中同一时间只能有一个线程访问python所提供的API。

    那么python是如何支持多线程的呢?

    在操作系统中系统通过时钟中断进行进程的调度,而python正是参考这个原理。在python内部维护了一个内部的时钟,来记录每个线程每个时钟周期执行命令的数量。

    >>> import sys

    >>> sys.getcheckinterval() #获取一个始终周期内执行指令数

    100

    当一个线程获得了python虚拟机的GIL后可以按顺序执行100条指令,然后挂起当前进程,切换下一个等待执行的线程。

    那么python如何选择下一个需要执行的线程呢?

    python并没有去实现一个线程优先级调度算法,而是将线程选择问题交给了底层的操作系统,也就是说python借用了底层操作系统所提供的线程调度机制来决定下一个执行的线程。

    因此,python使用的就是操作系统原生的线程,只是python在其基础之上提供了一套统一的抽象机制。

    线程切换

    在操作系统中,进程之间的切换需要不断保存和恢复进程之间的上下文环境,保证每一个进行都能在其对应的上下文环境中运行。python正是参考操作系统的切换机制,为每一个线程创建一个保存线程状态信息的PyFrameObject对象。在python中有有一个全局变量PyThreadState *_PyThreadState_Current用来保存当前活动线程的线程状态对象。

    下一线程切换需要的线程状态如何获取?

    在python中通过一个单项链表来管理所有的python线程对象(保护线程的状态信息和线程信息,例如线程id),当需要寻找一个线程对应的状态对象时,就遍历这个链表,搜索其对应的状态对象。

    这个状态对象链表并不会受到GIL的保护,而是有其专用的锁。

    需要注意

    当前活动的python线程不一定是获得了GIL的线程,例如“主线程获得了GIL,子线程还没有申请到GIL时也没有挂起,而且主线程和子线程都是操作系统原生的线程,操作系统可能在主线程和子线程之间进行切换(操作系统的线程切换是不受python虚拟机控制的,属于操作系统自身行为)”。python虚拟机的调度是一定是获得GIL基础之上的,而操作系统级的就不一定获得GIL了。

    虽有操作系统会把未获得GIL的线程切换为活动线程,但是该线程发现自身并没有获得GIL会自动挂起。

    只有当所有线程都完成了初始化操作,操作系统的线程调度和Python线程调度才会一致。那时,python的线程调度会迫使当前活动线程释放GIL,导致触发GIL中维护的Event内核对象,从而触发操作系统的线程调度。(在初始化完成之前,python线程调度和操作系统调度之间没有因果关系)

    阻塞调度和线程销毁

    在python中如果有raw_input等待输入的操作时将自身阻塞后,并将等待GIL线程唤醒,这种情况成为阻塞调度。

    在线程通过阻塞调度切换时,python内部的时钟周期技术_Py_Ticker依然会被保持,不会被重置。

    python的主线程销毁和子线程销毁是不同的,子线程只需要维护引用计数,而主线程还需要销毁运行环境。

    用户级互斥和同步

    上面讨论的GIL属于python内合计互斥,实现了保护内存的共享资源。而用户级互斥保护了用户程序中的共享资源。

    python中提供了lock机制来实现线程之间的互斥。当线程通过lock.acquire获得lock之后,子线程会因为等待lock而挂起,直到主线程释放lock之后才会被Python的线程调度机制唤醒。

    在线程执行过程中如果出现需要等待另一个lock资源的时候,需要将GIL转交给其他等待GIL的线程以避免死锁。

    展开全文
  • Python中的线程

    2020-12-23 11:46:27
    线程同步概念线程同步,线程间协同,通过某种技术,让一个线程访问某些数据时,其他线程不能访问这些数据,直到该线程完成对数据的操作.临界区(Critical Section) 互斥量(Mutex) 信号量(Semaphore) 时间(Event)Event事件...

    线程同步

    概念

    线程同步,线程间协同,通过某种技术,让一个线程访问某些数据时,其他线程不能访问这些数据,直到该线程完成对数据的操作.

    临界区(Critical Section) 互斥量(Mutex) 信号量(Semaphore) 时间(Event)

    Event事件

    Event事件,是线程间通信机制中最简单的实现,使用一个内部标记的flag,通过flag的True或False的变化来进行操作.

    名称

    含义

    set()

    标记设置为True

    clear()

    标记设置为False

    is_set()

    标记是否为True

    wait(timeout=None)

    设置等标记为True的时长,None为无限等待.等到返回True,未等到超时返回False,不设置默认无限等

    总结

    使用同一个Event对象的标记flag

    谁wait就是等到flag变为true,或等到超时返回False,不限制等待个数

    wait的使用

    Event的wait优于time.sleep,它会更快的切换到其他进程,提高并发效率.

    Lock(互斥锁,互斥量)

    锁,凡是存在共享资源争抢的地方都可以使用锁,从而保证只有一个使用者可以完全使用这个资源.

    一旦线程获得锁,其他试图获取锁的线程将被阻塞

    名称

    含义

    acquire(blocking=True,timeout=-1)

    默认阻塞,阻塞可以设置超时时间.非阻塞时,timeout禁止设置.成功获取锁,返回True,否则返回False

    release()

    释放锁,可以从任何线程调用释放.已上锁的锁,会被重置为unlocked未上锁的锁上调用,抛RuntimeError异常

    加锁,解锁

    一般来说,有加锁就需要解锁,一旦加锁后解锁前,还要执行一些代码,就可能抛异常,锁无法释放,但是当前线程就可能因为这个异常被终止,产生死锁.一般为逻辑问题.

    常用语句:

    使用try,,,finally语句保证锁的释放

    with上下文管理,锁对象支持上下文管理

    注意事项:

    少用.使用了锁,多线程访问被锁的资源时,就成了串行,要么排队执行,要么争抢执行

    加锁时间越短越好,不需要就立即释放锁

    一定要避免死锁

    递归锁RLock(可重入锁)

    递归锁,是线程相关锁,个人认为,锁的是一个线程

    线程A可获得重复锁,并可多次成功获取,不会阻塞.最后要在线程A中做和acquire次数相同的release.

    当锁未释放完,其他线程获取锁会被阻塞,知道当前持有锁的线程释放完锁

    Condition

    构造方法:Condition(lock= None),可以掺入一个Lock或者RLock锁对象,默认RLock

    名称

    含义

    acquire(*args)

    获取锁

    wait()

    等待或超时

    notify(n= 1)

    唤醒之多指定数目个数的等待线程,没有等待的线程就没有任何操作

    notify_all()

    唤醒所有等待的线程

    总结

    Condition用于生成者消费者模型中,解决生产者消费者速度匹配的问题.

    采用通知机制,效率极高

    使用方法:

    使用Condition,必须先acquire,用完了要release,默认使用RLock.最好的方式是使用with上下文

    消费者wait,等待通知

    生产者生产好消息,对消费者发送通知,可以使用notify或者notify_all方法.

    Barrier栅栏(路闸)

    wait超时

    semaphore信号量

    和Lock很想,信号量对象内部维护一个倒计数器,每一次acquire都会减1,当acquire方法发现技术为0就阻塞请求的线程,知道其他线程对信号量release后,计数大于0,恢复阻塞的线程.

    名称

    含义

    Semaphore(value=1)

    构造方法.value小于0,抛ValueError异常

    acquire()

    获取信号量,计数器减1,成功返回True

    release()

    释放信号量,计数器加1

    计数器永远不会低于0,因为acquire的时候,发现是0,都会被阻塞.

    from threading import Semaphore,Lock

    from threading import current_thread

    from threading import Thread

    import time

    sm = Semaphore(5)#5个马桶

    def task():

    sm.acquire()

    print(f'{current_thread().name} work')

    time.sleep(1)

    sm.release()

    for line in range(20):

    t.Thread(target=task)

    t.start

    信号量和锁

    锁,值允许同一个时间一个线程独占资源,它是特殊的信号量,即信号量计数器初值为1.

    信号量,可以多个线程访问共享资源,但这个共享资源数量有限.

    数据结构和GIL

    Queue

    标准库queue模块,提供

    FIFO的队列:先进先出

    LIFO的队列:后进先出

    优先队列:根据参数内,数字的大小进行分级,数值越小,优先级越高(字符串会有自己的算法,不建议使用)

    Queue是线程安全的,适用于多线程间安全的交换数据.内部使用了Lock,Condition

    import queue

    q = queue.Queue()

    q.put(1)

    q.put(2)

    q.put(3)

    print(q.get()) #1

    q = queue.LifoQueue()

    q.put(1)

    q.put(2)

    q.put(3)

    print(q.get()) # 3

    GIL全局解释器锁(Global Interpreter Lock)

    CPython在解释器进程级别有把锁.叫GIL全局解释器锁.

    GIL保证CPython进程中,只有一个线程执行字节码,甚至多核CPU情况下,也会当一个进程A中的线程执行时,阻塞其他CPU上A进程的线程.相当于,CPython中永远没有真正微观实际意义上的多线程.

    CPython中,IO密集型,使用多线程;CPU密集型,使用多继承,绕开GIL

    Ruby也有GIL,如果高并发的话,用erlang或者go

    ​Python中绝大多数内置数据结构读写都是原子操作.(即不会被优先级更高的线程打断,线程安全)

    ​由于GIL存在,Python的内置数据类型在多线程编程的时候就变程了安全的了,但是实际上他们本身不是线程安全类型.

    原子操作:原子操作,就是不能被更高等级中断抢夺优先的操作。由于操作系统大部分时间处于开中断状态,所以,一个程序在执行的时候可能被优先级更高的线程中断。而有些操作是不能被中断的,不然会出现无法还原的后果,这时候,这些操作就需要原子操作。就是不能被中断的操作。

    展开全文
  • 使用threading.Thread.is_alive()这个方法可以判断线程是否是存活状态。但是在现有的基础上不能够直到线程什么时候开始,什么时候结束,什么时候被打断。如果有一个或者多个线程需要在另外的一个线程到达一个确定的...

    使用threading.Thread.is_alive()这个方法可以判断线程是否是存活状态。但是在现有的基础上不能够直到线程什么时候开始,什么时候结束,什么时候被打断。

    如果有一个或者多个线程需要在另外的一个线程到达一个确定的点之后才执行下面的操作。这个时候可以使用threading.Event对象。

    Event对象和条件标记类似,允许线程等待某个事件发生,如果事件没有被设置而线程在登载该事件发生,那么线程就会被阻塞,直到事件被设置为止。当线程设置了这个事件是,就会唤醒所有等待的线程。

    1 from threading importThread, Event2 importtime3

    4

    5 defcountdown(n, start_evt):6 start_evt.wait()7 print('countdown start')8 while n > 1:9 print('T-minus', n)10 n -= 1

    11 time.sleep(3)12

    13 defcountUp(n, start_evt):14 start_evt.wait()15 print('countup start')16 while n < 100:17 print('T-minus', n)18 n += 1

    19 time.sleep(3)20

    21

    22 #Create the event object that will be used to signal starting

    23 start_evt =Event()24

    25 print('launching countdown')26 t = Thread(target=countdown, args=(10, start_evt))27 t.start()28 t2 = Thread(target=countUp, args=(1, start_evt))29 t2.start()30 print('threads to started')31 start_evt.set()

    View Code

    代码的运行结果是:

    threads to started

    countdown start

    T-minus 10

    countup start

    threads to started在countdown start和countup start之前运行。因为countdown和countup两个线程设置了Event事件的等待状态,当事件没有被触发的时候他们是不会开始运行的。

    注意:

    Event最好只用于一次型事件。因为一旦完成了设置Event对象就会被丢弃,如果在继续使用可能会造成问题。如果要重复的通知某个事件可以使用Condition

    Event对象的关键特性是唤醒所用等待的线程,如果只希望唤醒一个等待的线程可以使用Semaphore或者Condition

    展开全文
  • pythonthreading多线程一. Threading简介首先看下面的没有用Threading的程序import threading,timedef fun():s = 0for i in range(30):s += itime.sleep(0.1)print(s)if __name__ == '__main__':t = time.time()fun...
  • 这是一篇学习Python 线程相关的内容,记录一下以备复习和开发使用,技术有限,如有问题欢迎指出,多谢。一.GIL 全局解释器锁(cpython)1.为什么会有这个锁:为了线程安全,减少python使用者的上手难度GIL 使得同一个...
  • Python 线程开启多任务及回调函数

    千次阅读 2018-11-03 14:59:00
    # coding:utf-8 from time import sleep import thread def long_io(cb):  print "开始调用long_IO"  def func(callback):  print "start long_IO"  sleep(2) ... print...
  • 这篇文章主要介绍了Python线程条件变量Condition原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Condition 对象就是条件变量,它总是与某种锁相关联,...
  • Python 线程threading

    2021-11-01 10:59:32
    Python线程适用于I/O密集型 GIL的全称是Global Interpreter Lock(全局解释器锁),为了数据安全,GIL保证同一时间只能有一个线程拿到数据。所以,在python中,同时只能执行一个线程。而IO密集型,多线程能够有效...
  • 目录 一.Python 线程条件变量 Condition 函数 二.Python 线程条件变量 Condition 原理 ...对于线程线程之间的交互我们在前面的文章已经介绍了 Python 互斥锁 Lock / Python 事件 Event , 今天继续介绍一种线程
  • Python线程中,主线程的代码运行完后,如果还有其他子线程还未执行完毕,那么主线程会等待子线程执行完毕后再结束;这就会有产生一个问题,如果有一个线程被设置成无限循环,那么意味着整个主线程( Python ...
  • Python线程互斥锁

    2020-08-26 14:25:46
    一、线程间共享全局变量 多线程开发的时候共享全局变量会带来资源竞争效果,数据不安全。 import threading import time g_num = 0 def test1(num): global g_num for i in range(num): g_num += 1 print(f...
  • 常用用法t.is_alive()Python线程会在一个单独的系统级别线程中执行(比如一个POSIX线程或者一个Windows线程)这些线程将由操作系统来全权管理。线程一旦启动,将独立执行直到目标函数返回。可以通过查询一个线程对象...
  • python回调函数中使用多线程的方法

    千次阅读 2020-03-14 21:59:22
    这篇文章主要介绍了python回调函数中使用多线程的方法,需要的朋友可以参考下 下面的demo是根据需求写的简单测试脚本 #!/usr/bin/env python # coding: utf-8 # 第一个列表为依赖组件和版本号,后面紧跟负责人名称 # ...
  • Python线程同步的5种方式

    千次阅读 2021-01-30 11:30:12
    Python提供了多种线程间机制来保证多线程的同步。 1.Lock 下面我们对代码进行改造,导入threading中的Lock,并在每次+1 或是-1操作时获取锁,结束后释放锁。 import threading from threading import Lock lock = ...
  • 在定义socketserver服务端的时候一般会使用:server = socketserver.ThreadingTCPServer(settings.IP_PORT, MyServer)ThreadingTCPServer这个类便是可以支持多线程和TCP协议的socketserver模...
  • Python线程同步与线程

    千次阅读 多人点赞 2019-06-09 21:12:02
    文章目录Python线程同步与线程线程同步threading.Event对象threading.Timer定时器,延迟执行threading.Lock锁可重入锁RLockCondition条件锁,等待通知therading.Semaphore信号量threading.BoundedSemaphore有界...
  • 上一篇文章:Python线程专题8:使用锁的注意事项下一篇文章:Python线程专题10:queue、多线程按顺序执行线程没有任何方法可用于强制终止或挂起。这是设计上的原因,因为编写线程程序本身十分复杂。例如:如果某个线程...
  • Python线程间通信

    2020-12-12 09:36:32
    【摘要】如果各个线程之间各干...因为GIL的限制,python线程是无法真正意义上并行的。相对于异步编程,其性能可以说不是一个等量级的。为什么我们还要学习多线程编程呢,虽然说异步编程好处多,但编程也较为复杂,...
  • 在刚接触Python的时候时常听到GIL这个词,并且发现这个词经常和Python无法高效的实现多线程划上等号。本着不光要知其然,还要知其所以然的研究态度,博主搜集了各方面的资料,花了一周内几个小时的闲暇时间深入理解...
  • Python线程

    2020-11-24 08:31:01
    线程和进程计算机,用于计算的机器。计算机的核心是CPU,在现在多核心的电脑很常见了。为了充分利用cpu核心做计算任务,程序实现了多线程模型。通过多线程实现多任务的并行执行。现在的操作系统多是多任务操作系统。...
  • python线程

    2020-12-06 01:48:12
    线程线程的实质:进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程才是cpu上的执行单位。线程的特性:同一个进程内的多个线程共享该进程内的地址资源,但也任然有自己独立的存储空间...
  • 使用start和join代替run:import multiprocessing, sys, timedef f(icount, _sleepTime = 1):for i in range(icount):time.sleep(_sleepTime)print(_sleepTime)def main(args):m = multiprocessing.Process(target =...
  • 一、线程之间的几种通信方式 threading.Lock()/threading.RLock() - 互斥锁,在某一时刻只能有一个使用者访问该资源 threading.Condition() - 资源锁,可以提供挂起/唤醒等功能 threading.Event() - 可以提供...
  • Python线程并发编程

    2021-07-27 21:50:51
    Python中的一个线程对应与c语言中的一个线程。 GIL使得同一时刻一个CPU只能有一个线程执行字节码, 无法将多个线程映射到多个CPU上执行。 GIL会根据执行的字节码行数以及时间释放GIL,GIL在遇到IO的操作时候会主动...
  • python线程线程

    2020-11-25 18:09:29
    进程与线程的概念进程考虑一个场景:浏览器,网易云音乐以及notepad++ 三个软件只能顺序执行是怎样一种场景呢?另外,假如有两个程序A和B,程序A在执行到一半的过程中,需要读取大量的数据输入(I/O操作),而此时...
  • Python线程

    2020-12-15 11:04:38
    python中提供了函数和类两种方式使用多线程:创建多线程函数方式import threadingimport timedef run(sec):print('%s 线程开始了!' %threading.current_thread().name)time.sleep(sec)print('%s 线程结束了!' %...
  • 创建多线程 继承Thread类创建派生类,并重写__init__和run方法,实现自定义线程对象类: import threading import time class myThread(threading.Thread): def __init__(self, threadname): threading.Thread._...
  • Python threading(多线程)

    2020-11-29 14:29:43
    threading模块在较低级别thread模块之上构建更高级别的线程接口。一、threading模块定义了以下函数和对象:threading.active_count()等同于threading.activeCount(),返回Thread当前活动的对象数。返回的计数...
  • python如何切换线程

    2021-01-14 08:44:25
    条件对象能让一个线程 A 停下来,等待其他线程 B ,线程 B 满足了某个条件后通知(notify)线程 A 继续运行。线程首先获取一个条件变量锁,如果条件不足,则该线程等待(wait)并释放条件变量锁,如果满足就执行线程,也...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,964
精华内容 4,785
关键字:

python线程唤醒