PyQt5 - Безопасно ли расширять () до байтового массива из одного QThread, читая и переопределяя тот же байтовый массив из другого? - PullRequest
0 голосов
/ 25 января 2020

У меня есть GUI на основе PyQt5 в Python 3, где основной поток GUI вызывает Qthread с именем " DataHandler " для извлечения данных с сервера и обрабатывая его в фоновом режиме. DataHandler вызывает другой Qthread с именем «Рабочий», который должен одновременно сохранять извлеченные данные в файл. Весь код слишком велик. Соответствующие разделы моего кода для этого вопроса следующие.

DataHandler запускает все oop выборку двоичных данных с сервера и расширяет (), превращая их в bytearray с именем " data_arr", который доступен для DataHandler и Worker :

# Inside DataHandler
while(some_condition):
    recvBuf = myinstr.recv(1024)  # data received from a socket called myinstr. recvBuf is a bytes object
    self.WorkerObj.data_arr.extend(recvBuf)    # data_arr has been defined as a bytearray inside a class whose object is WorkerObj and one of whose methods is connected to Worker using moveToThread()

Между тем, Worker в al oop сохраняет добавление любых данных, присутствующих в data_arr , в двоичный файл с последующим переопределением для удаления предыдущих элементов:

# Inside Worker
startPos = 0
while(some_other_condition):
    endPosPlusOne = len(self.data_arr)
    bArray = self.data_arr[startPos:endPosPlusOne]
    I = bytearray(chain(*zip(bArray[2::4], bArray[3::4])))
    with open(fd1, 'ab') as f:   # writing into a file
        f.write(I)
    self.data_arr = self.data_arr[endPosPlusOne:]

Мне было интересно, приведет ли это к нежелательным результатам из-за какой-либо операции что может быть небезопасным. Ниже приведены некоторые ссылки, по которым я проходил исследование, прежде чем опубликовать этот вопрос, с основными интересующими их ссылками в кавычках:

  1. "Python pass- ссылка на объект " (Повторное назначение data_arr как data_arr [endPosPlusOne:] не должно перемещать его в другое место в памяти. Следовательно, если DataHandler пытается расширить это bytearray после того, как Worker переназначил его, это должно произойти без нареканий)
  2. "что не является потокобезопасным, это когда вы добавляете в один поток и вставляете в другой "
  3. ", выходящий из объекта списка, будет атомом c, потому что итерация по встроенному типу, такому как списки, реализована в собственном коде " (Так как bytes также является встроенным типом ( ссылается ), простираясь от байтов массив объектов до bytearray должен быть атомом c операция тоже)

, а также различные статьи / вопросы о использование блокировок переменных для обеспечения их поточной безопасности и использование объекта Lock () и его методов Release () и Acquire (), которые могут вызываться - но только в случае использования потоков из библиотеки Threading . Я не смог найти точные эквиваленты для Qthreads в PyQt5 , хотя обнаружил, что Qtcore.QMutex () используется здесь .

Однако, прежде чем принять решение о блокировке и мьютексе, я все еще застрял в путанице, вызванной противоречивыми вещами, о которых говорят ссылки (2) и (3) выше. Я также немного не уверен в своей комбинации выводов, сделанных из этих многочисленных источников (и были ли они сделаны правильно). Я был бы очень признателен, если бы кто-нибудь мог помочь мне устранить путаницу и подтвердить мои выводы. Если здесь действительно что-то не является поточно-ориентированным, пожалуйста, предложите также способы обеспечения безопасности потока, аналогичные блокировкам

Спасибо.

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