В Python 3.7 32-битные потоки «исчезают», но не 64-битные, если я не собираю задания и не жду их - PullRequest
3 голосов
/ 27 марта 2019

Я загружаю файл через chunking в python, используя requests для запросов http и concurrent.futures для потоков. Я заметил некоторое диссонирующее поведение между 32-битным и 64-битным Python 3.7 и хотел уточнить, что я делаю неправильно.

Я работаю на компьютере с Windows 10.

Указанное диссонирующее поведение включает в себя многопоточное выполнение, завершающееся преждевременно в 32-битной, но соответственно в 64-битной. Это, кажется, происходит всякий раз, когда у меня есть относительно большое количество потоков (16), распределенных по относительно большому количеству фрагментов для загрузки (52)

Всякий раз, когда я ожидаю своих задач в некоторой степени косвенным образом, я могу получить 64- и 32-битный режим для последовательного поведения. Смотрите код ниже.

Некоторые функции, которые я определил

def read_specific_chunk(file_path, chunk_disposition, chunk_size=CHUNK_SIZE_IN_BYTES):
    file_handle = open(file_path, 'rb')  # spawn new file handle for thread safe seek
    file_handle.seek(chunk_disposition * chunk_size)
    data = file_handle.read(chunk_size)
    file_handle.close()
    return data

def upload_chunk(chunk_position, file_transfer):
    file_chunk = read_specific_chunk(FILE_PATH,  # NOTE HOW THIS DEPENDS ON FILE PATH
                                     chunk_position)
    print("     Uploading chunk " + str(chunk_position + 1) + " of " + str(len(file_transfer.chunks)))
    place_chunk_url = CHUNK_PUT_URL.replace("#", str(file_transfer.fileTransferId)).replace("$", str(chunk_position))
    chunk_put_response = requests.put(url=place_chunk_url,
                                      data=file_chunk,
                                      headers=PUT_CHUNK_HEADERS,
                                      auth=HttpNegotiateAuth())

    if 200 <= chunk_put_response.status_code < 300:
        print("         PUT chunk " + str(chunk_position + 1) + " of " + str(
            len(file_transfer.chunks)) + " successfully for file transfer " + str(file_transfer.fileTransferId))
        return True

    print("         PUT " + str(chunk_position + 1) + " of " + str(len(file_transfer.chunks)) +
          " FAILED with status code " + str(chunk_put_response.status_code) + " for file transfer " + str(
        file_transfer.fileTransferId))
    return False

Мой проблемный код загрузки

with concurrent.futures.ThreadPoolExecutor(THREAD_COUNT) as executor:
    for chunkPosition in range(0, len(fileTransfer.chunks)):
        executor.submit(upload_chunk, chunkPosition, fileTransfer)

Мой код загрузки 64/32 последовательно ведет себя

with concurrent.futures.ThreadPoolExecutor(THREAD_COUNT) as executor:
    jobs = []
    results_done = []
    for chunkPosition in range(0, len(fileTransfer.chunks)):
        jobs.append(executor.submit(upload_chunk, chunkPosition, fileTransfer))
    for job in concurrent.futures.as_completed(jobs):
        # Read result from future
        result_done = job.result()
        # Append to the list of results
        results_done.append(result_done)

Я ожидаю, что каждый кусок будет загружен через проблемный код на 32- и 64-битном питоне. Однако, похоже, что некоторые потоки просто не выполняются в 32-битном Python. Также не выдается никакой видимой ошибки.

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