- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试创建一个函数,该函数将使用带有 9 个前导零的 sha1 算法生成哈希值。哈希基于一些随机数据,就像在并发挖掘中一样,我只想将 1 添加到哈希函数中使用的字符串。
为了更快,我使用了 Pool 类中的 map() 来使其在所有核心上运行,但如果我传递的 block 大于范围 (99999999),则会出现问题
def computesha(counter):
hash = 'somedata'+'otherdata'+str(counter)
newHash = hashlib.sha1(hash.encode()).hexdigest()
if newHash[:9] == '000000000':
print(str(newHash))
print(str(counter))
return str(newHash), str(counter)
if __name__ == '__main__':
d1 = datetime.datetime.now()
print("Start timestamp" + str(d1))
manager = multiprocessing.Manager()
return_dict = manager.dict()
p = Pool()
p.map(computesha, range(sys.maxsize) )
print(return_dict)
p.close()
p.join()
d2 = datetime.datetime.now()
print("End timestamp " + str(d2))
print("Elapsed time: " + str((d2-d1)))
我想创建类似于全局计数器的东西,以便在多线程运行时将其输入到函数中,但是如果我尝试 range(sys.maxsize) 我会得到一个 MemoryError (我知道,因为我不知道)有足够的 RAM,很少有),但我想将 range() 生成的列表分成 block 。这是可能的还是我应该尝试不同的方法?
最佳答案
嗨,Alin,欢迎来到 stackoverflow。
首先,是的,全局计数器是可能的。例如 multiprocessing.Queue或 multiprocessing.Value传递给 worker 。但是,从全局计数器获取新数字将导致锁定(并可能等待)计数器。这是可以而且应该避免的,因为您需要进行大量的计数器查询。我在下面提出的解决方案通过安装多个本地计数器来避免全局计数器,这些计数器一起工作,就像它们是单个全局计数器一样。
关于代码的 RAM 消耗,我发现两个问题:
computesha
返回 None
大部分时间都看重。这进入由 map
创建的迭代器(即使您没有分配 map
的返回值)。这意味着迭代器比所需的大得多。maxtasksperchild
选项(请参阅 multiprocessing.pool.Pool 的文档)。当您将此选项设置为 1000 时,它会在执行 1000 个任务后关闭进程并创建一个新进程,从而释放内存。但是,我想提出一个不同的解决方案,它可以解决这两个问题,非常内存友好并且运行速度更快(在我看来,经过 N<10 次测试)作为 maxtasksperchild
的解决方案选项:
#!/usr/bin/env python3
import datetime
import multiprocessing
import hashlib
import sys
def computesha(process_number, number_of_processes, max_counter, results):
counter = process_number # every process starts with a different counter
data = 'somedata' + 'otherdata'
while counter < max_counter: #stop after max_counter jobs have been started
hash = "".join((data,str(counter)))
newHash = hashlib.sha1(hash.encode()).hexdigest()
if newHash[:9] == '000000000':
print(str(newHash))
print(str(counter))
# return the results through a queue
results.put((str(newHash), str(counter)))
counter += number_of_processes # 'jump' to the next chunk
if __name__ == '__main__':
# execute this file with two command line arguments:
number_of_processes = int(sys.argv[1])
max_counter = int(sys.argv[2])
# this queue will be used to collect the results after the jobs finished
results = multiprocessing.Queue()
processes = []
# start a number of processes...
for i in range(number_of_processes):
p = multiprocessing.Process(target=computesha, args=(i,
number_of_processes,
max_counter,
results))
p.start()
processes.append(p)
# ... then wait for all processes to end
for p in processes:
p.join()
# collect results
while not results.empty():
print(results.get())
results.close()
此代码生成所需的 number_of_processes
然后调用 computesha
功能。如果number_of_processes=8
然后第一个进程计算计数器值 [0,8,16,24,...]
的哈希值,[1,9,17,25]
的第二个进程等等。
这种方法的优点:在 while 循环的每次迭代中 hash
的内存,和newHash
可以重用,循环比函数便宜,而且只 number_of_processes
必须进行函数调用,并且简单地忘记了无趣的结果。
一个可能的缺点是,计数器是完全独立的,每个进程都会精确地执行1/number_of_processes
整体工作的效率,即使有些工作比其他工作更快。最终,程序的速度与最慢的进程一样快。我没有测量它,但我想这是一个相当理论的问题。
希望有帮助!
关于python - 如何生成一个计数器来查找具有 9 个前导零的哈希值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56587410/
我是一名优秀的程序员,十分优秀!