ValueError: семафор или блокировка освобождаются слишком много раз при запуске - PullRequest
0 голосов
/ 22 сентября 2019

IDE - это pyCharm, использующий Python 3.7 в качестве интерпретатора.

Я нашел еще один вопрос, задающий этот вопрос, но он касался установки pip и не запуска программы.

from __future__ import print_function
import os
import time
from multiprocessing import Process, Lock, Queue
import debug
from table import Table
from truck import Truck
import package
import graph
import loader

# global variables for this program
mainGraph = graph.Graph()
mainTable = Table()
package.load('packageList.csv', mainTable)
graph.load('vertexList.csv', 'distanceList.csv', mainGraph)
mainLoader = loader.Loader(mainTable)

que = Queue()
lock = Lock()
truck1 = Truck(0, 0, node=mainGraph.get(1))
truck2 = Truck(1, 1, node=mainGraph.get(1))


class Dispatcher:
def __init__(self):
    self.clock = Timer()
    self.simulate = StartProgram(self.clock)
    self.process = Process(target=self.simulate.run, args=())

def start(self):
    self.process.start()

def terminate(self):
    self.process.terminate()

def interrupt(self):
    lock.acquire()

def resume(self):
    lock.release()


class Timer:
def __init__(self, begin=800, interval=1):
    self.time = begin
    self.interval = interval

    self.current = None
    self.isRunning = False
    self.isPaused = False

def start(self):
    if not self.isRunning:
        self.isRunning = True
        if not self.isPaused:
            self.current = self.time
        else:
            self.isPaused = False
    else:
        print("timer start error")

def stop(self):
    if self.isRunning:
        self.isRunning = False
        self.isPaused = False
    else:
        print("timer stop error")

def tick(self):
    if self.isRunning and not self.isPaused:
        self.current += self.interval
    else:
        print("timer tick error")

    if str(self.current)[-2:] == '60':
        self.current = self.current + 40

def pause(self):
    if self.isRunning:
        self.isPaused = True
    else:
        print("timer pause error")


class StartProgram:
def __init__(self, timer):
    self.timer = timer

def run(self):
    self.timer.start()

    for item in mainTable.items():
        item.setVertex(mainGraph)
        item.parseInstructions()
        if not item.delayed:
            item.setStatus('HUB')

    mainLoader.load()
    mainLoader.start(truck1)
    mainLoader.start(truck2)

    truck1.start(self.timer.current)
    print('next truck')
    truck2.start(self.timer.current)

    while True:
        lock.acquire()
        try:
            self.update()
        finally:
            if not que.empty():
                que.get(False)
            que.put(mainTable)
            lock.release()
            time.sleep(0.5)

def update(self):
    if self.timer.isRunning:
        self.timer.tick()

    response1 = truck1.update(self.timer.current)

    if response1 == 0:
        response1 = mainLoader.start(truck1)
        truck1.start(self.timer.current)
    if response1 == 1:
        truck1.endDay()
    response2 = truck2.update(self.timer.current)
    if response2 == 0:
        response2 = mainLoader.start(truck2)
        truck2.start(self.timer.current)
    if response2 == 1:
        truck2.endDay()

    for item in mainTable.lookup(status='STRING LOADED'):
        if self.timer.current >= item.time:
            item.setStatus('HUB')

    clear = lambda: os.system("cls")
    clear()

    print('Time: ' + str(self.timer.current))
    print()
    if not truck1.getIsDone():
        print(f"truck1:-load:{truck1.getLoadCount()} next stop:{truck1.next}\t arrival time:{truck1.getArrival()}")
    else:
        print('truck1 is done')
    if not truck2.getIsDone():
        print(f"truck2-load:{truck2.getLoadCount()} next stop: {truck2.next}\t arrival time {truck2.getArrival()}")
    else:
        print('truck2 is done')

    if truck1.getIsDone() and truck2.getIsDone():
        self.timer.stop()


def main():
if __name__ == '__main__':
    dispatcher = Dispatcher()
    dispatcher.start()
    val = None
    while True:
        val = input()
        if val == '1':
            dispatcher.interrupt()
            val = None
        elif val == '0':
            dispatcher.terminate()
            break
        val = input('1:resume \n2:exit \n3:print\n')
        if val == '1':
            dispatcher.resume()
            val = None
        elif val == '3':
            mainTable = que.get()
            mainTable.print()
            input('press enter to resume')
            dispatcher.resume()
        else:
            dispatcher.terminate()
            break


main()

При удалении раздела if __name__ == появляется ошибка, связанная с поддержкой замораживания.Поэтому я не знаю, правильно ли я это делаю или все в порядке.

Ошибка возникает в def main() после нажатия 1 и вызова dispatcher.resume().

edit: full traceback

Traceback (most recent call last):
  File "C:/Users/myname/PycharmProjects/p1/main.py", line 215, in <module>
    main()
  File "C:/Users/myname/PycharmProjects/p1/main.py", line 202, in main
    resume()
  File "C:/Users/myname/PycharmProjects/p1/main.py", line 45, in resume
   mainLock.release()
ValueError: semaphore or lock released too many times

Копировать из комментария : Я не уверен, правильно ли я понимаю, я поставил args = (mainlock,)), затем после start() я сделал self.process.joinОднако я получаю:

 Process Process-1: Traceback (most recent call last): 
 TypeError: run() takes 1 positional argument but 2 were given
...