从一个文件中读取同一行的线程

Posted

技术标签:

【中文标题】从一个文件中读取同一行的线程【英文标题】:Threads reading the same line from one file 【发布时间】:2022-01-05 00:52:22 【问题描述】:

我正在尝试在 python 中使用线程,我对线程很陌生。我希望线程从同一个文件中读取随机行,但所有线程都读取同一行。所以我试图阅读的文件的所有行都是 email:pass:another_line 格式的。我希望用多个线程从同一个文件中读取不同的行,但它用多个线程读取同一行。 因此,例如 1 个线程将返回 line1,第二个线程将返回 line2 但它的随机行。

import random
import threading

def email_pass_token():
    global email, pass2, token

    file = open("testing/pokens.csv").read().splitlines()
    acc_str = random.choice(file)

    num_lines = sum(1 for _ in file)
    print(num_lines)

    email = ":".join(acc_str.split(":", 1)[:1])

    pass2 = ":".join(acc_str.split(":", 2)[:2][1:])

    token = ":".join(acc_str.split(":", 3)[:3][2:])
email_pass_token()

def gen_acc():
    print(email, pass2, token)

threads = []
num_thread = input("Threads: ")
num_thread = int(num_thread)
for i in range(num_thread):
    t = threading.Thread(target=gen_acc)
    threads.append(t)
    t.start()

文件示例:

tqqe435ihwbta@oncemail.co.kr:#354946345e696$e30*417:another_line1
tkbzw543vwxzn@oncemail.co.kr:2e5548c543709!8@305-8(:another_line2
jcgeau43yphr@oncemail.co.kr:41c!954=7543cc^1#48fd_$*b5:another_line3
bqajs543qlqys@oncemail.co.kr:1f@e54d78^feb54355&6$50:another_line4
tqqeihw54bta@oncemail.co.kr:#3946345e696$e30*417:another_line5
tkbzwvwx543zn@oncemail.co.kr:2e58c5437709!8@305-8(:another_line6
jcgeauy453phr@oncemail.co.kr:41c!9=7543cc^1#48fd_$*b5:another_line7
bqajsqlq54ys@oncemail.co.kr:1f@ed78^feb53455&6$50:another_line8

【问题讨论】:

您需要为每个线程使用不同的种子。 您提供的代码不可运行。显示 tokens.csv 的样本,我将为您构建答案 所示代码不符合您的描述:线程从文件中读取,它们都读取相同的全局变量。 @DarkKnight prnt.sc/20xkt91,我相信它也可以是 .txt 文件,不一定是 .csv 文件 请将文件示例作为文本添加到问题中 【参考方案1】:

您没有运行在线程中选择行的功能。您正在做的是在仅打印三个变量emailpass2token 的线程中运行gen_acc。您选择行的代码位于email_pass_token,它只被调用一次。

【讨论】:

我将如何更改我的代码以选择不同的行? threading.Thread 中使用email_pass_token 而不是gen_acc。顺便说一句,您必须知道代码中会有竞争条件,因为多个线程正在修改相同的全局变量。您还必须在email_pass_token 内进行打印。【参考方案2】:

这是您可以做到的一种方法。请注意,如果 密码 包含冒号,这将不起作用。另外,我已经硬编码了线程数,但你明白了。

import random
from concurrent.futures import ThreadPoolExecutor

FILENAME = 'testing/pokens.csv'
NTHREADS = 5

def myfunc():
    with open(FILENAME) as infile:
        lines = infile.readlines()
        line = random.choice(lines).strip()
        tokens = line.split(':')
        return ' '.join(tokens)

def main():
    with ThreadPoolExecutor() as executor:
        futures = []
        printable = set()
        for _ in range(NTHREADS):
            future = executor.submit(myfunc)
            futures.append(future)
        for future in futures:
            printable.add(future.result())
        for p in printable:
            print(p)

if __name__ == '__main__':
    main()

【讨论】:

谢谢你的工作,但是比赛条件呢?如果我想消除所有重复的线程,我会怎么做?例如,1 个线程打印 line1,第二个线程打印 line2,第三个线程再次打印 line1。我将如何摆脱 thread3? 这里没有竞争条件。如果您想避免以您描述的方式重复,那么您应该更改线程函数 (myfunc) 以返回您在 main 函数中检查的值以查看是否需要打印它们 我已经编辑了答案以显示您如何可以避免重复输出

以上是关于从一个文件中读取同一行的线程的主要内容,如果未能解决你的问题,请参考以下文章

从文本文件中读取一行,然后用新文本 C# 替换同一行

如果字符串和数字在同一行,是否可以读取它们(从TXT文件中)。

如何仅使用命令行参数读取唯一行?

列更新后的 Java 对象更新

python读取大文件处理时使用多线程

C语言怎么做到从文件中读取一行数据,然后改变这一行内容