【问题标题】:How can I write simultanous data to csv file coming from multiple threads in Python如何将同时数据写入来自 Python 中的多个线程的 csv 文件
【发布时间】:2019-10-07 20:36:48
【问题描述】:

我从 thread_1 获取鼠标坐标(mouse_x,mouse_y),它适用于 tkinter。 我有另一个线程(thread_2)同时工作以使用opencv同时进行凝视方向估计(gaze_x,gaze_y)

现在我想将它们同时写在同一个 csvfile 上,而如果任何数据为 None 则不写。

我可以从每个线程获取一个 tmp 文件写入 csv 文件,但不能同时进行

with open(csv_filename, 'w', newline='') as csvfile:
    writer = csv.writer(csvfile, dialect=csv.excel, delimiter=',',
                        quotechar='|', quoting=csv.QUOTE_MINIMAL)
    writer.writerow(["mouse_x","mouse_y","gaze_x","gaze_y"])

def get_mouse_coordinates():
        def motion(event):
                  x, y = event.x, event.y
                  tmp = [x, y]
                  with open(csv_filename, 'a+', newline='') as csvfile:
                          writer = csv.writer(csvfile, delimiter=',',
                            quotechar='|', quoting=csv.QUOTE_MINIMAL) 
                           writer.writerow(list(tmp))
t1 = Thread(target=get_mouse_coordinates)
t1.start()


def get_gaze_coordinates
   .....
    gaze_x,gaze_y = ....

t2 = Thread(target=get_gaze_coordinates)
t2.start()

我尝试写入单独的冒号,但无法同时填充 csv 文件.... 我将不胜感激任何帮助... 最好的问候

编辑:我需要同时记录两个数据。在这里,我需要记录对象正在查看的目标(此处为鼠标指针)的非常精确的位置以及该对象的注视方向。我需要在给定的确切时刻将它们都写在同一行上,以便我可以关联。难道没有人同时采样两列数据进行关联吗?

【问题讨论】:

  • "现在我想将它们同时写入同一个 csvfile": 你为什么要这样做?得到写冲突?为了避免这种确切的情况(序列化写入),编写了很多代码(可能还有硬件接线)。幸运的是,您不能这样做,因为wiki.python.org/moin/GlobalInterpreterLock。还考虑到磁盘访问与 RAM 相比非常慢,在内存中尽可能多地计算会快得多,并且只写入大块,以减少写入次数(尽管缓冲发生在多个级别)。
  • 您使用互斥体(锁)一次只允许一个线程写入。您刷新文件输出以确保始终将整行​​写入 htread。

标签: python export-to-csv python-multithreading


【解决方案1】:

要同时从多个线程将数据写入单个文件,应创建同步机制。例如 - 另一个线程:

queuForSync1 = queue.Queue(1)
queuForSync2 = queue.Queue(1)
t1 = Thread(target=get_mouse_coordinates, args=(queuForSync1,))
# in get_mouse_coordinates you have to: queuForSync1.put(dataFromThread1)
t1.start()
...
t2 = Thread(target=get_gaze_coordinates, args=(queuForSync2,))
# in get_gaze_coordinates you have to: queuForSync2.put(dataFromThread2)
t2.start()
...
tSync = Thread(target=syncThread, args=(queuForSync1, queuForSync2, fileName))
tSync.start()
...
def syncThread(q1, q2, fileName):
    dataFromThread1 = None 
    dataFromThread2 = None 
    with open(fileName, 'a+', newline='') as csvfile:
        writer = csv.writer(csvfile, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL) 
        while True:  # Here - a sync Event May be used to get out of the Loop and Join Thread Nicely
            try:
                dataFromThread1 = q1.get(block=False)
            except Exception as ex:
                pass
            # ... same for dataFromThread2
            if dataFromThread1 is not None and dataFromThread2 is not None :
                writer.writerow(list(dataFromThread1, dataFromThread2))  # Here data will be written Into File.
                csvfile.flush()  # Important

此外 - 如果来自 1 个线程的数据没有变化,而来自线程 2 的数据不断变化 - 可能会创建一个缓冲区来存储从线程接收的最后数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多