多线程删除许多任务

时间:2018-12-18 17:26:47

标签: python-3.x multithreading

我想做一个简单的工作。我有一个由n个元素组成的列表,并且想要将该列表分为两个较小的列表,并使用线程执行简单的计算并将其附加到新列表中。我已经编写了一些测试代码,当我有少量元素(例如3000)时,它似乎可以正常工作。但是,当元素列表较大时(30,000),将删除超过12-20k的任务,并且附加操作将不会通过。

我已经读了很多关于什么构成线程安全和排队的知识。我相信这与此有关,但是即使在尝试使用Lock()之后,我仍然似乎无法获得线程安全的线程。

有人可以指出我正确的方向吗?干杯。

   # Seperate thread workload
a_genes = genes[0:count_seperator]
b_genes = genes[count_seperator:genes_count]

class GeneThread (Thread):
    def __init__(self, genelist):
        Thread.__init__(self)
        self.genelist = genelist
    def run(self):
        for gene in self.genelist:
            total_reputation = 0
            for local_snp in gene:
                user_rsid = rsids[0]
                if user_rsid is None:
                    continue

                rep = "B"

                # If multiplier is 0, don't waste time calculating
                if not rep or rep == "G" or rep == "U":
                    continue

                importance = 1

                weighted_reputation = importance * mul[rep]
                zygosity = "homozygous_minor"

                if rep == "B":
                    weighted_reputation *= z_mul[zygosity]

                #  Now we apply the spread amplifier, we raise the score to the power of the spread number
                rep_square = pow(spread, weighted_reputation)
                total_reputation += rep_square
            try:
                with lock:
                    UserGeneReputation.append(total_reputation)
            except:
                pass

start_time = time.time()
# Create new threads
gene_thread1 = GeneThread(genelist=a_genes)
gene_thread2 = GeneThread(genelist=b_genes)

gene_thread1.daemon, gene_thread2.daemon = True, True

# Start new Threads
gene_thread1.start()
gene_thread2.start()

print(len(UserGeneReputation))
print("--- %s seconds ---" % (time.time() - start_time))

Task with 3000 vs 30,000 size list

1 个答案:

答案 0 :(得分:1)

从广义上讲,线程有两种选择。您可以让他们自主,做他们的工作,然后安静地终止自己。或者,您也可以由其他一些线程来管理它们,这些线程监视它们的生命周期并知道何时完成。您的设计绝对需要第二个选项(获得所需的所有结果时还如何知道?),而您选择了第一个(将其设置为自我终止而不受到监视)。

不要使线程守护进程成为线程。相反,在启动它们之后,请等待两个线程完成。那不是最复杂或最优雅的解决方案,而是每个人都首先学到的解决方案。

此方法的问题在于,它迫使您的代码依赖于如何将工作分配给线程。这可能会导致性能问题,因为每次您想知道何时完成工作都不得不创建和销毁线程时,知道工作已经完成的唯一方法就是等待它。理想情况下,您将线程视为以某种方式完成工作的抽象,而必须等待工作完成的代码将等待工作本身完成(通过与工作本身相关联的某种同步),而不是等待线程完成完成。这样,您可以灵活地确定什么线程可以做什么工作,而不必在每次需要分配工作时都继续创建和销毁线程。

但是每个人都可以学习create / join方法。有时确实是最好的选择。即使使用其他方法,您也可能仍然具有外部创建/连接来首先创建线程,通常,请确保它们干净地完成以有序方式关闭程序。