Правильный способ работы со списками, которые постоянно меняются в python - PullRequest
0 голосов
/ 22 декабря 2018

У меня в Python есть список, в котором я всегда смотрю на его первый элемент, поработаю с ним, а затем удалю этот первый элемент.

Однако в то же время новые элементы могут быть вставлены вэтот список одновременно.Они также могут быть вставлены в позицию [0], как показано в следующем примере:

import threading
import time

class listener:

    def __init__(self):

        thread = threading.Thread(target=self.run, args=())
        thread.daemon = True
        thread.start()

    def run(self):

        while True:

            if time.monotonic() >= Car.cars_list[0].time:
                # other stuff happens to the 0th element
                # what happens if a new element is insrted just now in car_list?
                Cars.cars_list.pop(0)


class Car:
    # list that is always sorted according to car time parameter
    cars_list = []

    def __init__(self, id, model, time):

        self.id = id

        self.model = model

        self.time = time

        # method that inserts the car to cars_list based on time with simple binary search
        Car.insert(self, Carr.cars_list)

    @staticmethod
    def insert(x, a):
        lo = 0
        hi = len(a)

        while lo < hi:

            mid = (lo + hi) // 2

            if x.time < a[mid].time:

                hi = mid

            else:

                lo = mid + 1

        a.insert(lo, x) 

Что произойдет, если в 0-й элемент будет вставлена ​​новая машина, когда слушатель выполняет какие-то действия с текущим0-й элемент.

Мне кажется, что мне нужно заблокировать изменения cars_list, когда я работаю над ним в цикле True, включая строку pop (0).

Или, возможно, использоватьнекоторый тип буфера / очереди.Есть предложения?

1 Ответ

0 голосов
/ 23 декабря 2018

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

Если вы всегда удаляете первый элемент, list.pop уже атомный в Python.(Конечно, он может выдать, если список может быть (или станет) пустым.)

Также обратите внимание, что удаление из end списка происходит намного быстрее, чем с самого начала.

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