Использование Python 3.6 Threading со списком блокировок - PullRequest
0 голосов
/ 19 марта 2019

У меня есть исполняемый файл, который я использовал с различными начальными условиями. Он может запускаться сотни раз в зависимости от диапазона вводимых данных. Ускорение этого процесса является высоким приоритетом, и поэтому я попытался использовать нить и список блокировок.

Причиной списка блокировок является ограничение общей нагрузки на мой 6-ядерный процессор. Поэтому я выбрал 3 блокировки для этого поста, но планирую использовать 5.

Я показываю три разные попытки, каждая из которых проваливается по-своему.

  1. Диапазон входов никогда не увеличивается, т. Е. Только первая комбинация используется до выхода из программы. (зацикливание на lock_list и если lock.locked (): break)
  2. Каждый ввод выполняется n_locks раз. (цикл по списку блокировок)
  3. На самом деле не работает одновременно. (разрыв после каждой блокировки в lock_list)

Я не показываю реальные вызовы программы, а только способы, которыми я пытался реализовать Thread.

import threading
import time
import random

# Random seed for reproducibility
random.seed(123)

# Limit the number of active threads using locks
n_locks = 3
lock_list = list()

# Create a list that holds the desired number of locks
for i in range(n_locks):
    lock_list.append(threading.Lock())

# Some dummy data for use in the function to be threaded
aa = [1, 2, 3, 4, 5, 6, 7, 8]
bb = [3, 4, 3, 4, 3, 4, 3, 4]

# The function to be used, where execution time may vary
def multiply(a, b):
    print(a, b, a * b)
    time.sleep(random.random() * 0.5)


# Show the inputs and outputs without threading
print('Unthreaded output...')

for d1, d2 in zip(aa, bb):
    multiply(d1, d2)

# The same function, but using 'with lock:'
def multiply_threaded(l, a, b):
    with l:
        print(a, b, a * b)
        time.sleep(random.random() * 1.0)


# Here's where I'm having a problem...
print('\nThreaded Ouptut, 1st Try')
for d1, d2 in zip(aa, bb):
    for lk in lock_list:
        if lk.locked():
            break
        else:
            threading.Thread(target=multiply_threaded, args=(lk, d1, d2)).start()

time.sleep(1.5)
print('The data set is never advanced...')
# Sleep to wait for the 2nd attempt...

# 2nd Try
print('\nThreaded Ouptut, 2nd Try')
for d1, d2 in zip(aa, bb):
    for lk in lock_list:
        threading.Thread(target=multiply_threaded, args=(lk, d1, d2)).start()

time.sleep(5.5)
print('The data set is used 3 times...')


# 3rd Try
print('\nThreaded Ouptut, 3rd Try')
for d1, d2 in zip(aa, bb):
    for lk in lock_list:
        threading.Thread(target=multiply_threaded, args=(lk, d1, d2)).start()
        break

time.sleep(5.5)
print("Doesn't appear to be executed concurrently...")

Ниже вывод:

Unthreaded output...
1 3 3
2 4 8
3 3 9
4 4 16
5 3 15
6 4 24
7 3 21
8 4 32

Threaded Ouptut, 1st Try
1 3 3
1 3 3
1 3 3
The data set is never advanced...

Threaded Ouptut, 2nd Try
1 3 3
1 3 3
1 3 3
2 4 8
2 4 8
2 4 8
3 3 9
4 4 16
3 3 9
5 3 15
4 4 16
3 3 9
5 3 15
4 4 16
5 3 15
6 4 24
6 4 24
6 4 24
7 3 21
7 3 21
8 4 32
8 4 32
7 3 21
8 4 32
The data set is used 3 times...

Threaded Ouptut, 3rd Try
1 3 3
2 4 8
3 3 9
4 4 16
5 3 15
6 4 24
7 3 21
8 4 32
Doesn't appear to be executed concurrently...

Process finished with exit code 0

То, что я ожидаю увидеть, похоже на вывод без резьбы, и попробуйте №3, за исключением того, что порядок не обязательно должен быть в том порядке, в котором были заданы входные данные, поскольку функция сна использовалась для имитации загрузки исполняемого файла.

Спасибо, что нашли время, чтобы прочитать!

РЕДАКТИРОВАТЬ: я использую os.system ("C: \ my_exe.exe> ​​C: \ my_output.txt) в фактическом потоке. Я не могу получить доступ к exe или вспомогательным файлам, когда они используются, поэтому я сделал копии, чтобы каждый из них мог использовать one.d

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...