这就是场景:我有一个父进程,它产生了几个子进程。现在必须允许每个子进程运行两秒钟(理想情况下是cpu时间),之后父进程将让孩子进入睡眠状态或进行一些工作。这个循环继续。还可以在其间终止一些子过程。将要产生的子过程是由一些不可信赖的人编写的代码。 (这个问题让我想起循环调度)
我的解决方案和研究:
明显的解决方案:让父母睡两秒钟,然后醒来并控制孩子。在这里,我们考虑到墙上的时间,每个过程可能无法获得合理的两秒执行时间。
解决方案二:使用带有RLIMIT_CPU的prlimit()并将一个大的hardlimit和softlimit设置为最初的两秒。随后,软限制可以升高两秒。然后子流程获得SIGXCPU信号。
可以为每个过程分配不同的信号(实时信号)(达到33的上限)。现在,在收到SIGXCPU信号后,必须使用os.kill()将指定的信号发送给父级。这里的问题是子进程必须自愿将信号发送给父进程。通过迟发信号,子流程可能会获得额外的时间。
解决方案三:使用setitimer()和子进程中的ITIMER_VIRTUAL。 SIGVTALRM信号被发送到子进程。它必须将不同的信号(如上所述)转发给父进程。该解决方案具有与先前解决方案相同的问题。
所有这三种解决方案都是灾难。我正在寻找更好的解决方案。一些解释的最小代码将非常有用。
答案 0 :(得分:0)
同样的问题被问到here。
一种可能的解决方案是在ptrace
下(父项)运行子流程。执行此操作时,父会收到有关即将发送给其ptrace
个孩子的任何信号的通知,并且父母可以决定如何处理这些待处理信号(有可能)忽略信号,或将信号转发给孩子;或终止孩子等。)
将要产生的子流程是由一些不可信赖的人编写的代码。
ptrace
解决方案还允许您查看子进程正在执行的操作,并阻止它执行某些系统调用。
如果没有这个,子进程可以fork
并转到sleep
,不消耗执行时间(使用无子进程占用无限的CPU时间)。
另请参阅this有关Linux下jails的文章。沙箱中的当前技术水平似乎是seccomp-bpf,例如Firejail。
答案 1 :(得分:0)
我为正在寻找自我的人写这篇文章,因为我一直在研究自己。
尝试使用schedule库。计划任务变得非常容易和直观。
import schedule
import time
def job():
print("I'm working...")
schedule.every(10).minutes.do(job)
schedule.every().hour.do(job)
schedule.every().day.at("10:30").do(job)
schedule.every().monday.do(job)
schedule.every().wednesday.at("13:15").do(job)
while True:
schedule.run_pending()
time.sleep(1)
如果以串行方式安排它们,请小心,因为它没有考虑到任务运行所花费的时间。例如,如果计划的作业需要2分钟,那么schedule.every()。hour.do(job)实际上将每62分钟运行一次。
如果要使用子流程并行安排任务,请检查readthedocs中的FAQ问题。有几种方法的链接可以帮助/指导您完成操作。
如果要将参数传递给函数,请执行以下操作:
schedule.every().monday.do(job, parameter1, parameter2)