Python——如何用另一个脚本共享实时数据。

时间:2021-09-17 03:54:50

I am trying to find easiest way to share real time variable from one script to another. First script will read seonsor data and other will make calculations based on real-time data from the first script. I want to run them separetly. I want to be able to kill second script and run it again without any problems.

我试图找到最简单的方法,将实时变量从一个脚本共享到另一个脚本。第一个脚本将读取seonsor数据,其他的将根据第一个脚本的实时数据进行计算。我想把它们分开运行。我希望能够杀死第二个脚本,并在没有任何问题的情况下运行它。

I would like to have second script to print real-time data whenever it is started.

我希望有第二个脚本在开始时打印实时数据。


Update:

更新:

I have finaly got some time to play with os.pipe(). I have managed to run some scripts that use os.fork() but when I tried to split one script into two separate programs I start haveing some issues.

我有一些时间和os.pipe()一起玩。我已经成功地运行了一些使用os.fork()的脚本,但是当我尝试将一个脚本拆分为两个独立的程序时,我开始有一些问题。

Program I have initated and was working:

我的计划是:

    #!/usr/bin/python
     import os, sys
     r, w = os.pipe() 
     processid = os.fork()
     if processid:
           os.close(w)
           r = os.fdopen(r)
           print("Parent reading")
           str = r.read()
           print("text =", str)   
           sys.exit(0)
     else:
           os.close(r)
           w = os.fdopen(w, 'w')
           print("Child writing")
           w.write("Text written by child...")
           w.close()
           print("Child closing")
           sys.exit(0)

Based on that script I tried to write my own separate scripts.

基于这个脚本,我尝试编写自己的独立脚本。

First script that prints time to pipe:

打印时间到管道的第一个脚本:

   #!/usr/bin/python
   import os, sys, time
   stdout = sys.stdout.fileno()
   r, w  = os.pipe()
   #os.close(r)
   w = os.fdopen(w, 'w')
   i = 0
   while i < 1000:
         i = i + 1
         w.write('i' + " ")
         time.sleep(1)

Second script that reads time from pipe:

从管道读取时间的第二个脚本:

   #!/usr/bin/python

   import os, sys, time
   r, w = os.pipe()
   r = os.fdopen(r)
   str = r.read()
   print(str)

When I try to run my scripts nothing happens. Any suggestions what am I doing wrong? Maybe I missed some details about standard input and output and os.pipe()?

当我试图运行我的脚本时,什么都没有发生。有什么建议吗?也许我漏掉了一些关于标准输入和输出的细节。

1 个解决方案

#1


0  

Edit: Just to illustrate a crude example of a possible poison pill approach. Unfortunately, python's (multiprocessing) Queues do not implement a peek call so I used a second queue:

编辑:只是为了说明一个可能的毒丸方法的一个粗糙的例子。不幸的是,python的(多处理)队列没有实现peek调用,所以我使用了第二个队列:

Writer:

作者:

import time
import sys

def write(queue_msg, queue_term):
     i = 0
     sys.stdout = open("writer" + ".out", "w")
     sys.stderr = open("writer_err" + ".out", "w")
     stop_writing = True
     while i<1000:
        if not(stop_writing):
            print("Writer at iteration ", i)
            queue_msg.put("Iteration " + str(i)) # put a value inside the queue
            i += 1
        time.sleep(1)
        q_term_val = queue_term.get() if not(queue_term.empty()) else "CONTINUE" #Check that the queue is not empty otherwise put a non important value
        print(q_term_val)
        if q_term_val == "START":
            print("Start working")
            stop_writing = False 
        elif q_term_val == "STOP":
            print("Stop working")
            stop_writing = True 
        sys.stderr.flush() #flush stdout and stderr to disk 
        sys.stdout.flush()

Reader:

读者:

import time
import sys

def read(queue_msg, queue_term):
    sys.stdout = open("reader" + ".out", "w") #redirect process stdout to file "reader.out"
    sys.stderr = open("reader_err" + ".out", "w")
    queue_term.put("START")
    while True:
        value = queue_msg.get()
        print(value) # write value to reader.out filer as mentioned above
        if int(value.split(" ")[1]) > 10:
            print("Stop working, I am tired...")
            queue_term.put("STOP")
            time.sleep(5) #wait 5 seconds before sending start to the worker
            queue_term.put("START")
        time.sleep(1)
        sys.stderr.flush()
        sys.stdout.flush()

Main:

主要:

import reader
import writer
import multiprocessing as mp

def main():

    q_msg = mp.Queue()
    q_term = mp.Queue()
    r = mp.Process(target=reader.read, args=(q_msg, q_term,))
    w = mp.Process(target=writer.write, args=(q_msg, q_term,))
    r.start()
    w.start()
    print("Processes started, check that in your folder there are a reader.out and a writer.out files")

if __name__ == "__main__": # "workaround" needed on Windows
    main()

And you should have the reader.out file (also writer.out) in your folder showing that the reader indeed read values written to the queue by the writer and in "writer.out", you can see that the writer stops writing to the queue when he received the poison pill. And the reader after the time.sleep(5) call starts again from the right position.

你应该有读者。在您的文件夹中,显示读者确实阅读了作者和“writer”中写入队列的值。你可以看到,当他收到毒丸时,他停止了写信。而读者在时间之后。睡眠(5)又从正确的位置开始。

#1


0  

Edit: Just to illustrate a crude example of a possible poison pill approach. Unfortunately, python's (multiprocessing) Queues do not implement a peek call so I used a second queue:

编辑:只是为了说明一个可能的毒丸方法的一个粗糙的例子。不幸的是,python的(多处理)队列没有实现peek调用,所以我使用了第二个队列:

Writer:

作者:

import time
import sys

def write(queue_msg, queue_term):
     i = 0
     sys.stdout = open("writer" + ".out", "w")
     sys.stderr = open("writer_err" + ".out", "w")
     stop_writing = True
     while i<1000:
        if not(stop_writing):
            print("Writer at iteration ", i)
            queue_msg.put("Iteration " + str(i)) # put a value inside the queue
            i += 1
        time.sleep(1)
        q_term_val = queue_term.get() if not(queue_term.empty()) else "CONTINUE" #Check that the queue is not empty otherwise put a non important value
        print(q_term_val)
        if q_term_val == "START":
            print("Start working")
            stop_writing = False 
        elif q_term_val == "STOP":
            print("Stop working")
            stop_writing = True 
        sys.stderr.flush() #flush stdout and stderr to disk 
        sys.stdout.flush()

Reader:

读者:

import time
import sys

def read(queue_msg, queue_term):
    sys.stdout = open("reader" + ".out", "w") #redirect process stdout to file "reader.out"
    sys.stderr = open("reader_err" + ".out", "w")
    queue_term.put("START")
    while True:
        value = queue_msg.get()
        print(value) # write value to reader.out filer as mentioned above
        if int(value.split(" ")[1]) > 10:
            print("Stop working, I am tired...")
            queue_term.put("STOP")
            time.sleep(5) #wait 5 seconds before sending start to the worker
            queue_term.put("START")
        time.sleep(1)
        sys.stderr.flush()
        sys.stdout.flush()

Main:

主要:

import reader
import writer
import multiprocessing as mp

def main():

    q_msg = mp.Queue()
    q_term = mp.Queue()
    r = mp.Process(target=reader.read, args=(q_msg, q_term,))
    w = mp.Process(target=writer.write, args=(q_msg, q_term,))
    r.start()
    w.start()
    print("Processes started, check that in your folder there are a reader.out and a writer.out files")

if __name__ == "__main__": # "workaround" needed on Windows
    main()

And you should have the reader.out file (also writer.out) in your folder showing that the reader indeed read values written to the queue by the writer and in "writer.out", you can see that the writer stops writing to the queue when he received the poison pill. And the reader after the time.sleep(5) call starts again from the right position.

你应该有读者。在您的文件夹中,显示读者确实阅读了作者和“writer”中写入队列的值。你可以看到,当他收到毒丸时,他停止了写信。而读者在时间之后。睡眠(5)又从正确的位置开始。