简体   繁体   English

在Python中暂停执行

[英]Pause Execution in Python

I am implementing a Python plugin that is part of a larger C++ program. 我正在实现一个Python插件,它是一个较大的C ++程序的一部分。 The goal of this program is to allow the user to input a command's actions in Python. 该程序的目标是允许用户使用Python输入命令的动作。 It currently receives a string from the C++ function and runs it via the exec() function. 当前,它从C ++函数接收一个字符串,并通过exec()函数运行它。 The user can then use an API to affect changes on the larger C++ program. 然后,用户可以使用API​​来影响较大的C ++程序的更改。

The current feature I am working on is a pause execution feature. 我正在使用的当前功能是暂停执行功能。 It needs to remember where it is in the code execution as well as the state of any local variables, and resume execution once a condition has been met. 它需要记住它在代码执行中的位置以及任何局部变量的状态,并在满足条件后恢复执行。 I am not very familiar with Python, and I would like some advice how to implement this feature. 我对Python不太熟悉,我想对如何实现此功能提出一些建议。 My first design ideas: 我的第一个设计思路:

1) Using the yield command. 1)使用yield命令。 This seemed to be a good idea at the start since when you use the next command it remembers everything I needed it to, but the problem is that yield only returns to the previous level in the call stack as far as I can tell. 一开始这似乎是个好主意,因为当您使用下一条命令时,它会记住我需要的所有内容,但是问题是,据我所知,yield只能返回到调用堆栈中的上一级。 So if the user calls a function that yields it will simply return to the user's code, and not the larger C++ program. 因此,如果用户调用产生函数的函数,它将仅返回用户代码,而不返回较大的C ++程序。 As far as I can tell there isn't a way to propagate the yield command up the stack??? 据我所知,没有办法在堆栈上传播yield命令。

2) Threading Create a main python thread that creates a thread for each command. 2)线程创建一个主python线程,该线程为每个命令创建一个线程。 This main thread would spawn a thread for each command executed and kill it when it is done. 该主线程将为每个执行的命令生成一个线程,并在完成时将其杀死。 If it needs to be suspended and restarted it could do so through a queue of locks. 如果需要暂停并重新启动它,则可以通过锁队列来完成。

Those were the only two options I came up with. 这些是我提出的仅有的两个选择。 I am not sure the yield function would work or is what it was designed to do. 我不确定yield函数是否可以正常工作或设计的目的。 I think the Threading approach would work but might be overkill, and take a long time to develop. 我认为线程化方法会起作用,但可能会过大,并且需要很长时间才能开发。 I also was looking for some sort of Task Module in Python, but couldn't find exactly what I was looking for. 我也在寻找Python中的某种Task Module,但找不到确切的内容。 I was wondering if anyone has any other suggestions as I am not very familiar with Python. 我想知道是否有人对我不太熟悉,所以还有其他建议。

EDIT: As mentioned in the comments I did not explain what needs to happen when the script "Pauses". 编辑:如评论中所述,我没有解释脚本“暂停”时需要发生什么。 The python plugin needs to allow the C++ program to continue execution. python插件需要允许C ++程序继续执行。 In my mind this means A) returning if we are talking about a single threaded approach, or B) Sending a message(Function call?) to C++ 在我看来,这意味着A)如果我们正在谈论单线程方法,则返回,或者B)向C ++发送消息(函数调用?)

EDIT EDIT: As stated I didn't fully explain the problem description. 编辑编辑:如上所述,我没有完全解释问题的描述。 I will make another post that has a better statement of what currently exists, and what needs to happen as well as providing some sudo code. 我将发表另一篇文章,更好地说明当前存在的内容,需要发生的事情以及提供一些sudo代码。 I am new to Stack Overflow, so if this is not the appropriate response please let me know. 我是Stack Overflow的新手,所以如果这不是适当的答复,请告诉我。

Whenever a signal is sent in Python, execution is immediately paused until whatever signal handler function is being used is finished executing; 每当使用Python发送信号时,执行都会立即暂停,直到使用完任何信号处理程序函数为止; at that point, the execution continues right where it left off. 此时,执行将从中断处继续执行。 My suggestion would be to use one of the user-defined signals ( signal.SIGUSR1 and signal.SIGUSR2 ). 我的建议是使用用户定义的信号之一( signal.SIGUSR1signal.SIGUSR2 )。 Take a look at the signal documentation here: 在这里查看signal文档:

https://docs.python.org/2/library/signal.html https://docs.python.org/2/library/signal.html

At the beginning of the program, you'd define a signal handler function like so: 在程序的开始,您将定义一个信号处理程序函数,如下所示:

def signal_pause(signum, frame):
  if signum == signal.SIGUSR1:
    # Do your pause here - function processing, etc
  else:
    pass

Then in the main program somewhere, you'll switch out the default signal handler for the one you just created: 然后在主程序中的某个位置,您将为刚刚创建的信号处理程序切换默认的信号处理程序:

signal.signal(signal.SIGUSR1, signal_pause)

And finally, whenever you want to pause, you'll send the SIGUSR1 signal like so: 最后,无论何时要暂停,您都将发送SIGUSR1信号,如下所示:

os.kill(os.getpid(),signal.SIGUSR1)

Your code will immediately pause, saving its state, and head to the signal_pause function to do whatever you need to do. 您的代码将立即暂停,保存其状态,然后转到signal_pause函数以执行所需的任何操作。 Once that function exits, normal program execution will resume. 该函数退出后,将恢复正常程序执行。

EDIT: this assumes you want to do something sophisticated while you're pausing the program. 编辑:这假设您要在暂停程序的同时做一些复杂的事情。 If all you want to do is wait a few seconds or ask for some user input, there are some much easier ways ( time.sleep or input respectively). 如果您只想等待几秒钟或要求用户输入一些信息,则可以使用一些更简单的方法(分别是time.sleepinput )。

EDIT EDIT: this assumes you're on a Unix system. 编辑编辑:这假定您在Unix系统上。

If you need to communicate with a C program, then sockets are probably the way to go. 如果您需要与C程序进行通信,则套接字可能是您的最佳选择。

https://docs.python.org/2/library/socket.html https://docs.python.org/2/library/socket.html

One of your two programs acts as the socket server, and the other connects to it as the socket client. 您的两个程序之一充当套接字服务器,另一个程序作为套接字客户端连接到它。 When you want the C++ program to continue, you use socket.send() to transmit a continue message. 当您希望C ++程序继续运行时,可以使用socket.send()来发送继续消息。 Then your Python program would use socket.recv() , which will cause it to wait around until it receives a message back from the C++ program. 然后,您的Python程序将使用socket.recv() ,这将使其等待,直到收到来自C ++程序的消息。

If you need two programs to send signals to each other, this is probably the safest way to go about it. 如果您需要两个程序来相互发送信号,这可能是最安全的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM