如果另一个并发进程具有搜索结果,则通知进程停止

时间:2019-01-21 14:32:01

标签: python-3.x

这是你们以前可能遇到的问题。我正在尝试处理多个文本文件,这些文本文件包含由\ r \ n(CRLR)符号分隔的哈希。一旦其中一个进程进行了比较并找到了散列,我希望其余进程通过中断其循环而退出。当我已经得到结果时,没有理由让他们继续读取其他文件。

import os.path
from multiprocessing import Pool
import time
import os
import hashlib

def process_hash_file(password, path):
    ''' Process one file: read each line and search for a given hash '''
    m = hashlib.sha1()
    m.update(password)
    password_sha1 = m.hexdigest().upper()
    print("SHA1: " + password_sha1)
    isFound = False
    hash_sha1 = ""
    times_found = ""
    start_time = time.time()
    with open(path) as f_hashes:
        for hash in f_hashes:
            hash_sha1 = hash.split(':')[0]
            times_found = hash.split(':')[1]
            print('[D] Checking ' + hash_sha1 + " : " + times_found[:len(times_found)-1] + " against " + password_sha1)
            if hash_sha1 == password_sha1:
                isFound = True
                print(hash_sha1 + " matches password!")
                break
    if isFound:
        print(str(password) + "(" + password_sha1 + ") match found this many times: " + times_found)
        print("process took: " + str(time.time() - start_time) + " seconds to finish!")
    else:
        print("No match was found for: " + password + "(" + password_sha1 + ")")
        print("process took: " + str(time.time() - start_time) + " seconds to finish!")

现在,我的问题是我找不到发信号通知其他进程停止的方法。

我试图创建一个附加了锁的变量(非常幼稚的方法),以尝试停止其他进程,但是由于某种原因,该操作失败。现在,我知道python中存在促进类似行为的“基础结构”,我只是找不到合适的基础结构,或者我只是不知道如何正确地使用它们来实现我的目标。

import multiprocessing
import time
import os

mylock = multiprocessing.Lock()
trigger_stop = False


def continue_until_triggered():
    ''' Count slowly towards a large number '''
    print('process id:', os.getpid())
    for num in range(0, 999999):
        time.sleep(1)
        """Wait for lock to release"""
        with mylock:
            if trigger_stop:
                print("trigger was hit, stopping!")
                break


def trigger_after_time_passed(time_passed):
    ''' Makes continue_until_triggered stop by triggering stop'''
    print('process id:', os.getpid())
    time.sleep(time_passed)
    """Wait for lock to release"""
    with mylock:
        trigger_stop = True


if __name__ == '__main__':
    print("starting processes...")
    print('parent process:', os.getppid())
    m1 = multiprocessing.Process(name='continue_until_triggered',
                                 target=continue_until_triggered)
    m1.start()

    m2 = multiprocessing.Process(name='trigger_after_time_passed',
                                 target=trigger_after_time_passed,
                                 args=(5,))
    m2.start()
    print("done processing!")
Outputs:
starting processes...
parent process: 3500
done processing!
process id: 6540
process id: 3736
[trigger_stop is never set to True, therefore the process doesn't stop or I might be dead locking here]

我想要的是这样的结果:

Output: 
starting processes...
parent process: 3500
done processing!
process id: 6540
process id: 3736
[trigger_stop is set to True]
trigger was hit, stopping!
[3736 exits]
[6540 exits]

1 个答案:

答案 0 :(得分:2)

正常变量不在进程之间共享。每个进程都有自己的变量副本,您需要一些支持共享状态的文件,例如Event

https://repl.it/@zlim00/signaling-processes-to-stop-if-another-concurrent-process-ha

import multiprocessing
import time
import os

def continue_until_triggered(mylock, trigger_stop):
    ''' Count slowly towards a large number '''
    print('process id:', os.getpid())
    for num in range(0, 999999):
        time.sleep(1)
        """Wait for lock to release"""
        with mylock:
            if trigger_stop.is_set():
                print("trigger was hit, stopping!")
                break


def trigger_after_time_passed(time_passed, mylock, trigger_stop):
    ''' Makes continue_until_triggered stop by triggering stop'''
    print('process id:', os.getpid())
    time.sleep(time_passed)
    """Wait for lock to release"""
    with mylock:
        trigger_stop.set()


if __name__ == '__main__':
    print("starting processes...")
    print('parent process:', os.getppid())

    mylock = multiprocessing.Lock()
    trigger_stop = multiprocessing.Event()
    m1 = multiprocessing.Process(name='continue_until_triggered',
                                 target=continue_until_triggered,
                                 args=(mylock, trigger_stop))
    m1.start()

    m2 = multiprocessing.Process(name='trigger_after_time_passed',
                                 target=trigger_after_time_passed,
                                 args=(5, mylock, trigger_stop))
    m2.start()
    print("done processing!")

输出:

starting processes...
parent process: 58648
done processing!
process id: 62491
process id: 62492
trigger was hit, stopping!