python为每个线程读取不同的行

2024-09-29 19:24:39 发布

您现在位置:Python中文网/ 问答频道 /正文

我编写这段python代码是为了进行测试。其背后的思想是读取csv文件的行,将数据分配给变量,并使用线程打印这些变量。但是,我希望该函数能够逐行读取每个线程的csv文件,但我没有找到如何做到这一点

csv文件如下所示:

    name        lastname
1   John        B.
2   Alex        G.
3   Myriam      R.
4   Paul        V.
5   Julia       L.
6   Margot      M.

代码如下:

import csv
import threading

class main():

    def print_names():

        with open('names.csv', 'r') as csv_file:
            csv_reader = csv.DictReader(csv_file)
            for row in csv_reader:
                data = name, lastname = row['name'], row['lastname']

        screenlock.acquire()
        print(name, lastname)
        screenlock.release()


if __name__ == '__main__':

    screenlock = threading.BoundedSemaphore(1)

    with open('names.csv', 'r') as csv_file:
        csv_reader = csv.DictReader(csv_file)
        rows_count = len(list(csv_reader))

    threads = []
    for _ in range(rows_count):
        t = threading.Thread(target=main.print_names)
        threads.append(t)
        t.start()
    for thread in threads:
        thread.join()

电流输出为:

Margot M.
Margot M.
Margot M.
Margot M.
Margot M.
Margot M.

但我希望得到以下输出:

John B.
Alex G.
Myriam R.
Paul V.
Julia L.
Margot M.

PS:如果我的问题不太容易理解,很抱歉,这是我在这里的第一篇帖子


Tags: 文件csvnameinfornamesmainreader
2条回答

问题似乎是您在每个线程中读取整个文件。然后,在

for row in csv_reader:
    data = name, lastname = row['name'], row['lastname']

只存储last(name,lastname)。我不熟悉csv模块,但我假设它返回一个生成器。 如果是这种情况,您可以共享生成器,使每个线程从中读取一次,或者为每个线程提供线程索引,使其可以忽略所有剩余的行

选项1:这并不总是保持文件顺序,但是如果您使用线程处理每一行,我想顺序并不重要。。。如果顺序很重要,线程可能不是最佳解决方案

def print_names(csv_reader):
    row = next(csv_reader)
    data = name, lastname = row['name'], row['lastname']

    screenlock.acquire()
    print(name, lastname)
    screenlock.release()

if __name__ == '__main__':

    screenlock = threading.BoundedSemaphore(1)

    with open('names.csv', 'r') as csv_file:
        csv_reader = csv.DictReader(csv_file)
        rows_count = len(list(csv_reader))

    with open('names.csv', 'r') as csv_file:
        csv_reader = csv.DictReader(csv_file)

        threads = []
        for _ in range(rows_count):
            t = threading.Thread(target=print_names, args=(csv_reader,))
            threads.append(t)
            t.start()
        for thread in threads:
            thread.join()

选项2:这也不能确保订单的一致性。。。每个线程读取一次文件。。这可能是大型文件的一个巨大瓶颈

def print_names(idx):
    with open('names.csv', 'r') as csv_file:
        csv_reader = csv.DictReader(csv_file)
        row = [r for i,r in enumerate(csv_reader) if i == idx][0]
        data = name, lastname = row['name'], row['lastname']

    screenlock.acquire()
    print(name, lastname)
    screenlock.release()

if __name__ == '__main__':

    screenlock = threading.BoundedSemaphore(1)

    with open('names.csv', 'r') as csv_file:
        csv_reader = csv.DictReader(csv_file)
        rows_count = len(list(csv_reader))

    threads = []
    for idx in range(rows_count):
        t = threading.Thread(target=print_names, args=(idx,))
        threads.append(t)
        t.start()
    for thread in threads:
        thread.join()

下面是您的代码的具体情况:

  1. 逐行读取整个文件以计算行数,然后将其关闭

  2. 在文件中创建和启动尽可能多的线程,每个线程执行以下操作:

    a。打开同一个文件(每个线程都有自己要读取的文件副本)

    b。逐行读取整个文件

    c。为每行分配data = name, lastname = row['name'], row['lastname']

    d。关闭文件

    e。打印上次循环迭代(文件的最后一行)中的namelastname的值

  3. 等待所有线程完成

每个线程将读取与for循环的最后一次迭代相同的行,因此namelastname在每个线程中自然是相同的

读取文件通常最好由一个线程来完成,因为普通文件不适合随机访问。如果您需要对每一行进行大量的处理,那么在主线程中读取文件,并将每一行传递给要处理的线程,将使您受益匪浅

相关问题 更多 >

    热门问题