Взаимное исключение в Python - PullRequest
0 голосов
/ 21 марта 2020

Я написал программу на python, которая обрабатывает два потока. Один поток строит графики из массива, другой добавляет данные в массивы, которые создает другой поток. Поскольку оба потока обращаются к одним и тем же массивам, я решил использовать условную переменную для обеспечения взаимного исключения при доступе к указанному массиву. Однако я забыл его реализовать.

Меня одновременно интересовало время выполнения для разных частей кода. Поэтому я использовал функцию time.time (), чтобы установить sh время выполнения. Когда я удалил части, измеряющие время выполнения, функция больше не работала.

Это заставило меня понять, что я забыл реализовать условную переменную. Я сделал, и это сработало. Однако я не понимаю, почему программа работала без резюме, когда я измерял время? Было ли это просто из-за того, что добавленное время выполнения второго потока уменьшило вероятность одновременного доступа к массиву для обоих потоков?

В приведенном ниже коде я прокомментировал использование CV out.

import matplotlib.animation as animation
from matplotlib import style
from threading import Thread, Condition
import time
import random
import sys

style.use('fivethirtyeight')
condition = Condition()
xs = []
ys = []
i = 0
running = 1
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)

def getData():
    return random.randrange(1, 10, 1)

def animate(i):
    #condition.acquire()
    ax1.clear()
    ax1.plot(xs, ys)
    #condition.release()

def terminate():
    global running
    print("Goodbye")
    running = 0
    sys.exit()

class sensorHandler(Thread):
    def run(self):
        while(running):
            startTime = time.time()
            global i
            number = getData()
            #condition.acquire()
            if i<10:
                i = i+1
                xs.append(float(i))
                ys.append(float(number))
            else:
                ys[:] = ys[1:]
                ys.append(float(number))
            #condition.release()
            print(time.time()-startTime)


if __name__=="__main__":
    sensorHandler().start()
    ani = animation.FuncAnimation(fig, animate, interval=100)
    plt.show()
    terminate()´´´

1 Ответ

0 голосов
/ 22 марта 2020

Сложно понять наверняка, потому что довольно сложно проверить 1 , но я ожидаю, что удаление time.time() выявит сбой синхронизации, зависящий от времени, который не будет отображаться с дополнительными затратами на выполнение time.time().

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

Схема многопоточности здесь безопасна (когда CV правильно реализована), потому что все действия matplotlib выполняются в одном потоке, но следует отметить, что matplotlib не является поточно-безопасным , и если Действия matplotlib должны быть разделены между несколькими потоками, тогда доступ к исполнителям должен быть правильно сериализован.


1 Потенциальные методы проверки имеют тенденцию быть разрушительными - если вычислительные затраты на выполнение time.time достаточно, чтобы скрыть проблему, которая также подходит для большинства обычных методов отладки.

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