提问人:Mika 提问时间:7/31/2023 最后编辑:Mika 更新时间:7/31/2023 访问量:61
在 python3 中苦苦挣扎
Struggling with multiprocessing in python3
问:
我正在尝试启动接收器进程。这是一个类,它只从套接字接收数据。例如,它只会在 csv 文件中写入行。 我将通过管道发送退出信号。在此信号之后,单独进程中的 while 循环将结束,并且该单独的写入器进程将完成。
import multiprocessing
from datetime import datetime
import time
import datetime
import csv
from multiprocessing import Process, Pipe
class CSVWriter:
def __init__(self, pipe: multiprocessing.Pipe):
self.pipe = pipe
def write(self):
with open(f'RTD.csv', 'w') as csvfile:
writer = csv.DictWriter(csvfile, delimiter=',', fieldnames=['date'])
while self.pipe.recv() != 'exit':
writer.writerow({'date': (datetime.datetime.now())})
time.sleep(1)
print('exit csv')
pipe_receiver, pipe_sender = Pipe()
def write_csv(pipe):
csv_writer = CSVWriter(pipe=pipe)
csv_writer.write()
process = Process(target=write_csv, args=(pipe_receiver,))
process.start()
pipe_sender.send(input())
process.join()
process.close()
但是,与我的期望不同,它不会创建文件。或者,如果我输入了错误的退出键,它会创建空文件。
我在管道上挣扎了大约 2 天,无法理解问题所在。我将不胜感激任何信息。
PS 我正在使用进程 bc,我需要非常快速地从套接字接收数据(例如,我只是将数据写入文件)。所以,我不能使用线程。
答:
首先,客户端打开文件并输入 -语句,然后将文件刷新到磁盘并关闭。 在通过管道发送数据之前阻止执行,这仅在调用 时发生。将 的结果直接传递到管道中,其结果由 接收。当返回 'exit' 以外的内容时,将再次调用,但这一次,父进程将不再发送数据,因为 'pipe_sender.send(input())' 语句只执行了一次。因此,将无限期阻塞,从而阻止 -statement 退出。因此,文件的写入缓冲区永远不会刷新,并且它保持为空。此外,父进程随后会调用,这会导致死锁:with
pipe.recv()
pipe_sender.send()
input()
recv()
input()
recv()
recv()
with
join()
父进程正在等待子进程退出,它无法这样做,因为它正忙于等待来自父进程的数据。recv()
子进程正在等待父进程使用 向其发送数据,它无法执行此操作,因为它正忙于等待子进程退出。recv()
当输入“exit”时,将完全跳过 while 循环,程序的其余部分按预期执行;在这种情况下,也会创建一个空文件。
最好的解决方案是使用线程(它们通常比进程创建得更快,并且更容易处理,因为您可以访问相同的变量和对象)或者(因为您调用 join 并等待进程),在同一个程序中完全完成所有操作
评论
multiprocessing
'spawn'
if __name__ == '__main__':
input()
"exit"