暂停线程并从另一个脚本中唤醒它

时间:2016-01-19 18:10:53

标签: python multithreading python-2.7

我想要一个线程等待来自另一个脚本的消息。

我不想使用time.sleep(),因为它会产生时间间隔,如果我需要我的线程唤醒并继续运行,它可能会延迟太多,我的目标是获得最快的性能。我不会使用while(NOT_BEING_CALLED_BY_THE_OTHER_THREAD),因为它会占用我的CPU而且我的目标是尽可能降低我的CPU使用率(因为会有更多的线程在同一时间执行相同的操作) )。

在伪代码中,它应该如下所示:

do_stuff()
wait_for_being_called() #Rise immediately after being called (or as soon as possible)
do_more_stuff()

这样做的目的是使用在被调用之前不可用的数据,有一个脚本可以检查数据的可用性(单个线程在运行),还有许多等待它们需要的数据(单个脚本检查它,如果数据可用则应调用它们。它有点像c ++中的std::condition_variable,只是我希望我的其他外部脚本能够唤醒等待的脚本。

我怎样才能实现这样的目标? check_for_events.py应包含哪些内容?

#check_for_events.py
for data_node in data_list:
        """
        What do I do here, assuming I have the thread id?
        """

1 个答案:

答案 0 :(得分:1)

如果您有两个不同的脚本,可能最好使用的是select。这是我的意思的一个例子:

from __future__ import print_function
import select
import socket
import sys
import time
from random import randint


def serve():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    port = randint(10000, 50000)
    with open('.test_port', 'w') as f:
        f.write('{}'.format(port))
    sock.bind(('127.0.0.1', port))
    sock.listen(1)

    not_finished = True
    while not_finished:
        try:
            print('*'*40)
            print('Waiting for connection...')
            conn, addr = sock.accept()
            print('Waiting forever for data')
            select.select([conn], [], [])

            data = conn.recv(2048)
            print('got some data, so now I can go to work!')

            print('-'*40)
            print('Doing some work, doo da doo...')
            print('Counting to 20!')
            for x in range(20):
                print(x, end='\r')
                time.sleep(0.5)
            print('** Done with work! **')
            print('-'*40)

            conn.close()
        except KeyboardInterrupt:
            print('^C caught, quitting!')
            not_finished = False


def call():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    print('Connecting')
    with open('.test_port') as f:
        port = int(f.read())
    sock.connect(('127.0.0.1', port))
    sock.sendall(b'This is a message')
    sock.close()
    print('Done')


if __name__ == '__main__':
    if 'serve' in sys.argv:
        serve()
    elif 'call' in sys.argv:
        call()

这允许呼叫者实际与跑步者通信信息。您也可以将其设置为侦听多个传入连接,并将它们从池中扔到select,如果这是您需要的。

但是如果你真的只想阻止另一个程序给你打电话,那么你可以通过移除conn, add = sock.accept()conn.close()之间的部分来使这更简单(当然除了你自己的工作之外) )。