0

我将在不同的机器上运行一个脚本,我需要弄清楚所有实例何时完成,以便我可以运行一个最终函数(它将由最后一个完成的脚本运行)。

大多数情况下,它们会在不同的时间开始和结束,但我希望能够处理多个同时完成的任何情况。我一直在使用线程进行测试,但我无法找到一个强大的解决方案。这是我的想法:

尝试附加到文件:
与下面我向文件添加唯一 UTF8 字符的类似代码。当字符数与线程匹配且字符与当前字符相同时,表示最后一个函数已运行。不幸的是,最后一个函数可以在其他函数完成写入之前读取文件。

尝试重命名(显然一个文件可以重命名多次):

def func(file_format, num_threads):
    for index in xrange(num_threads):
        try:
            os.rename(file_format.format(index), file_format.format(index + 1))
            print str(index) + '\n'
            break
        except WindowsError:
            pass

file_format = 'W:/tmp/peter/race_condition_test/unique_id.{}'
num_threads = 6
if __name__ == '__main__':
    with open(file_format.format(0), 'w') as f:
        pass
    for _ in range(num_threads):
        t = Thread(target=partial(func, file_format, 6))
        t.start()

输出:

0
0
0
1
1
1

通过检查文件夹中的写入文件:

def func(iteration, folder, file_name, num_threads):
    path = os.path.join(folder, file_name)
    with open(path.format(iteration), 'w') as f:
        pass
    print str(os.listdir(folder)) + '\n'

num_threads = 6
folder = 'W:/tmp/peter/race_condition_test'
file_name = 'unique_id.{}'
if __name__ == '__main__':
    for i in range(num_threads):
        t = Thread(target=partial(func, i, folder, file_name, num_threads))
        t.start()

输出:

['unique_id.4', 'unique_id.2', 'unique_id.3', 'unique_id.0', 'unique_id.5', 'unique_id.1']
['unique_id.4', 'unique_id.2', 'unique_id.3', 'unique_id.0', 'unique_id.5', 'unique_id.1']
['unique_id.4', 'unique_id.2', 'unique_id.3', 'unique_id.0', 'unique_id.5', 'unique_id.1']
['unique_id.4', 'unique_id.2', 'unique_id.3', 'unique_id.0', 'unique_id.5', 'unique_id.1']
['unique_id.4', 'unique_id.2', 'unique_id.3', 'unique_id.0', 'unique_id.5', 'unique_id.1']
['unique_id.4', 'unique_id.2', 'unique_id.3', 'unique_id.0', 'unique_id.5', 'unique_id.1']

只运行一次最终代码非常重要,因为它使用外部程序的 API 来更新某些内容。如果我不得不使用 final 方法并有机会多次运行,那不会是世界末日,但是还有其他好的方法可以解决这个问题吗?

4

1 回答 1

1
def func(iteration, folder, file_name):
    path = os.path.join(folder, file_name)
    with open(path.format(iteration), 'w') as f:
        pass
    print str(os.listdir(folder)) + '\n'

num_threads = 6
folder = 'W:/tmp/peter/race_condition_test'
file_name = 'unique_id.{}'
if __name__ == '__main__':
    threads = []
    for i in range(num_threads):
        t = Thread(target=partial(func, i, folder, file_name))
        threads.append(t)
        t.start()
    for t in threads:
        t.join()    # you need to join to know when they all finish

或者您可以在多处理中使用 ThreadPool (不知道为什么它隐藏在 Multiprocess 类中而不是 Thread 类中,但它就在那里。

于 2018-10-19T16:26:53.473 回答