@StickPunk

Как изменять переменную из двух процессов?

Есть такой вот код.

from ctypes import c_wchar_p
from random import choice, randint
from time import sleep
from multiprocessing import Value, Process


class Values(object):

    def __init__(self):
        self._text = Value(c_wchar_p, None)

    @property
    def text(self):
        return self._text.value

    def add_text(self, text: str):
        if self._text.value:
            self._text.value += text
        else:
            self._text.value = text

    def clear_text(self):
        self._text.value = ""


class A(Process):

    def __init__(self, storage: Values):
        Process.__init__(self)

        self.storage = storage

    def run(self) -> None:

        while True:

            self.storage.add_text(choice(["a", "b", "c"]))
            print(self.storage.text)
            sleep(1)


class B(Process):

    def __init__(self, storage: Values):
        Process.__init__(self)

        self.storage = storage

    def run(self) -> None:

        while True:

            a = randint(0, 10)

            if a > 5:
                pass
            else:
                self.storage.clear_text()
                print(self.storage.text)

            sleep(0.001)


if __name__ == '__main__':
    s = Values()

    a = A(s)
    b = B(s)

    a.start()
    b.start()


Как я понял принты прекращаются потому что 2 процесса одновременно пытаются изменить переменную. Возможно ли это обойти?
  • Вопрос задан
  • 134 просмотра
Пригласить эксперта
Ответы на вопрос 2
Точно не из за этого - у процессов отдельные адресные пространства.
Попробуйте после print добавить sys.stdout.flush()
Ответ написан
Vindicar
@Vindicar
RTFM!
У тебя сначала self.storage.clear_text(), а потом print(self.storage.text). Это вообще какой смысл имеет?
В итоге у тебя хоть что-то выведется только если звёзды сойдутся, и процесс-поставщик успеет засунуть свой контент в общую переменную в промежутке между этими вызовами.
Защити общий ресурс мьютексом (Lock), чтобы гонки не было, и поправь порядок операций.

Ну и вообще, ты уверен что так можно шарить указатель? Когда ты добавляешь новый текст к строке, может потребоваться перевыделить память под строку, что изменит адрес, на который указывает указатель. Ты уверен, что
1. оба процесса будут иметь один и тот же адрес
2. память по этому адресу будет расшарена для обоих процессов
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы