Pregunta

¡mundo! En los gráficos de tortuga en Python, es posible crear varios objetos de tortuga y manipularlos con sus métodos, hacia adelante, hacia atrás ... Quería experimentar con hilos, así que escribí una clase roscada llamada MyTurtlemanipulator.

from threading import Thread
from cTurtle import Turtle 
import random

class MyTurtleManipulator(Thread):
  def __init__(self, turtle):
    Thread.__init__(self)
    self.turtle=turtle
  def run(self):
    actions=[Turtle.forward, Turtle.right, Turtle.left]    
    while True:      
      action=random.choice(actions)      
      action(self.turtle, random.randint(1,25))

turtles=[Turtle() for i in range(5)]
threads=[MyTurtleManipulator(turtle) for turtle in turtles]

for thread in threads:
  print(thread)
  thread.start()

Con el experimento esperaba ver a todas las tortugas moverse "simultáneamente" y al azar, pero cuando ejecuto el programa recibo estos errores:

<MyTurtleManipulator(Thread-1, initial)>
<MyTurtleManipulator(Thread-2, initial)>
<MyTurtleManipulator(Thread-3, initial)>
<MyTurtleManipulator(Thread-4, initial)>
<MyTurtleManipulator(Thread-5, initial)>
>>> Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python3.1/threading.py", line 516, in _bootstrap_inner
    self.run()
  File "/home/rfrm/test.py", line 13, in run
    action(self.turtle, random.randint(1,25))
  File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 1162, in forward
    checkargs((int, float))
  File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 1131, in _go
    ende = self._position + self._orient * distance
  File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 2266, in _goto
    (start, self._position),
  File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 419, in _drawline
    cl.append(-y)
  File "<string>", line 1, in coords
  File "/usr/lib/python3.1/tkinter/__init__.py", line 2123, in coords
    self.tk.call((self._w, 'coords') + args)))
RuntimeError: main thread is not in main loop

Exception in thread Thread-2:
Traceback (most recent call last):
  File "/usr/lib/python3.1/threading.py", line 516, in _bootstrap_inner
    self.run()
  File "/home/rfrm/test.py", line 13, in run
    action(self.turtle, random.randint(1,25))
  File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 1203, in right
    checkargs((int, float))
  File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 2300, in _rotate
    self._orient = self._orient.rotate(delta)
  File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 2085, in _update
    for t in screen._turtles:
  File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 2219, in _drawturtle
    screen._drawpoly(titem, shape, fill=fc, outline=oc,
  File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 384, in _drawpoly
    cl.append(-y)
  File "<string>", line 1, in coords
  File "/usr/lib/python3.1/tkinter/__init__.py", line 2123, in coords
    self.tk.call((self._w, 'coords') + args)))
RuntimeError: main thread is not in main loop

Exception in thread Thread-3:
Traceback (most recent call last):
  File "/usr/lib/python3.1/threading.py", line 516, in _bootstrap_inner
    self.run()
  File "/home/rfrm/test.py", line 13, in run
    action(self.turtle, random.randint(1,25))
  File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 1162, in forward
    checkargs((int, float))
  File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 1131, in _go
    ende = self._position + self._orient * distance
  File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 2270, in _goto
    screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)),
  File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 419, in _drawline
    cl.append(-y)
  File "<string>", line 1, in coords
  File "/usr/lib/python3.1/tkinter/__init__.py", line 2123, in coords
    self.tk.call((self._w, 'coords') + args)))
RuntimeError: main thread is not in main loop

Exception in thread Thread-4:
Traceback (most recent call last):
  File "/usr/lib/python3.1/threading.py", line 516, in _bootstrap_inner
    self.run()
  File "/home/rfrm/test.py", line 13, in run
    action(self.turtle, random.randint(1,25))
  File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 1162, in forward
    checkargs((int, float))
  File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 1131, in _go
    ende = self._position + self._orient * distance
  File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 2270, in _goto
    screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)),
  File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 419, in _drawline
    cl.append(-y)
  File "<string>", line 1, in coords
  File "/usr/lib/python3.1/tkinter/__init__.py", line 2123, in coords
    self.tk.call((self._w, 'coords') + args)))
RuntimeError: main thread is not in main loop

Exception in thread Thread-5:
Traceback (most recent call last):
  File "/usr/lib/python3.1/threading.py", line 516, in _bootstrap_inner
    self.run()
  File "/home/rfrm/test.py", line 13, in run
    action(self.turtle, random.randint(1,25))
  File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 1203, in right
    checkargs((int, float))
  File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 2300, in _rotate
    self._orient = self._orient.rotate(delta)
  File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 2085, in _update
    for t in screen._turtles:
  File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 2219, in _drawturtle
    screen._drawpoly(titem, shape, fill=fc, outline=oc,
  File "/usr/local/lib/python3.1/dist-packages/cTurtle.py", line 384, in _drawpoly
    cl.append(-y)
  File "<string>", line 1, in coords
  File "/usr/lib/python3.1/tkinter/__init__.py", line 2123, in coords
    self.tk.call((self._w, 'coords') + args)))
RuntimeError: main thread is not in main loop

¿Qué significa esto? Lo que significa "el hilo principal no está en el bucle principal" significa. Gracias por tu ayuda.

¿Fue útil?

Solución

Esto parece ser una limitación de Python/Tkinter Como se describe aquí, tortuga y hilos no son amigos

Otros consejos

Esto tiene sus limitaciones, pero aún puede ser posible. La respuesta está en sus desorden de error:

RuntimeError: el hilo principal no está en el bucle principal

Limite sus operaciones de tortuga/tkinter al hilo principal. En mi reelaboración de su ejemplo a continuación, he usado la caja fuerte del hilo cola Estructura de datos para comunicarse entre los hilos y la tortuga:

from threading import Thread, active_count
from turtle import Turtle, Screen
import queue
import random

QUEUE_SIZE = 1  # set higher the more hardware threads you have
ACTIONS = [Turtle.forward, Turtle.right, Turtle.left]
COLORS = ['red', 'black', 'blue', 'green', 'magenta']

class MyTurtleManipulator(Thread):

    def __init__(self, turtle):
        super().__init__()
        self.turtle = turtle

    def run(self):
        for _ in range(100):
            actions.put((self.turtle, random.choice(ACTIONS), random.randint(1, 30)))

def process_queue():
    while not actions.empty():
        turtle, action, argument = actions.get()
        action(turtle, argument)

    if active_count() > 1:
        screen.ontimer(process_queue, 100)

actions = queue.Queue(QUEUE_SIZE)

for color in COLORS:
    turtle = Turtle('turtle')
    turtle.color(color)
    turtle.setheading(random.randint(0, 360))
    MyTurtleManipulator(turtle).start()

screen = Screen()

process_queue()

screen.mainloop()

¡Establecí la cola_size en 1 ya que estoy en una máquina con solo dos hilos! Tengo curiosidad por saber si todo funciona correctamente en una máquina con más hilos y un Queue_Size ~ = #Threads - 1

enter image description here

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top