为什么它会告诉我“RuntimeError:线程只能启动一次”?

2024-05-28 18:19:05 发布

您现在位置:Python中文网/ 问答频道 /正文

如果我运行此代码,它会给我错误消息

RuntimeError:线程只能启动一次

一个窗口弹出正确的图像,但它被冻结,屏幕立即崩溃。我认为线程无法在while循环中工作,但是如果是这样的话,我该如何修复代码呢

import pygame
import random
import time
import threading
pygame.init()

#Creates a window for the game
screen = pygame.display.set_mode((1200,720))
#Names the window
pygame.display.set_caption("Pigeon Shootout")

#crosshair location
cx = 550
cy = 300
#pigeon1 location
p1x = 1000
p1y = 400
#pigeon2 location
p2x = 600
p2y = 400
#pigeon3 location
p3x = 200
p3y = 400

#Names images 
Background = pygame.image.load('Background.png')
Crosshair = pygame.image.load('Crosshair.png')
Pigeon = pygame.image.load('Pigeon.png')

def pigeon_spawn():
    #Generates random number than spawns pigeon acordingly
    num = random.randint(1,3)
    if num == 1:
        screen.blit(Pigeon, (p1x, p1y))
    elif num == 2:
        screen.blit(Pigeon, (p2x, p2y))
    else:
        screen.blit(Pigeon, (p3x, p3y))
    time.sleep(5)

#Puts pigeon_spawn run separately
pig = threading.Thread(target=pigeon_spawn)


run = True
while run == True:
    
    #imputs background and crosshair
    screen.blit(Background, (0,0))
    screen.blit(Crosshair, (cx, cy))
    
    #starts pigeon_spawn
    pig.start()
    
    #enables you to quit when you press the x at the top
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
    
    #makes crosshair move with the arrow keys
    keys = pygame.key.get_pressed()
    if keys[pygame.K_UP]:
        cy -= 1
    if keys[pygame.K_DOWN]:
        cy += 1
    if keys[pygame.K_LEFT]:
        cx -= 1.5
    if keys[pygame.K_RIGHT]:
        cx += 1.5
    screen.blit(Crosshair, (cx, cy))
    pygame.display.update()    

pygame.quit() 

Tags: therunimportiflocationkeysscreenpygame
3条回答

RuntimeError: threads can only be started once

简单地说,一个线程只能启动一次,不能启动两次

import threading
import time

def function():
    print("Hello!")
    time.sleep(3)
    print("Bye")

#Starts thread1
thread1 = threading.Thread(target=function)
thread1.start()

#Starts thread2
thread2 = threading.Thread(target=function)
thread2.start()

#Tries to start thread 2, but it is already started, so it will give a RunTimeError
thread2.start()

控制台:

Hello!
Hello!
Traceback (most recent call last):
  File "C:\Users\Lukas\Desktop\test322.py", line 16, in <module>
    thread2.start()
  File "C:\Users\Lukas\AppData\Local\Programs\Python\Python39\lib\threading.py", line 865, in start
    raise RuntimeError("threads can only be started once")
RuntimeError: threads can only be started once
Bye
Bye

如果您真的想在一个单独的线程中反复运行函数pigeon_spawn中的代码,为什么不将该代码放在一个循环中,这样线程就永远不会退出呢

如果确实需要一次又一次地启动一个新线程,那么每次都需要创建一个新的线程对象。只需将线程的创建移动到while循环中:

while run == True:
    ...
    threading.Thread(target=pigeon_spawn).start()
    ...

你的方法行不通。不能在线程中使用Surface指示符blitaSurface。整个场景需要在应用程序循环中不断重画。添加一个变量pigeon_pos变量,该变量将在全局名称空间中存储Pigeon位置。在交易中的循环中更改变量blit应用程序循环中的Pigeon。在循环之前启动线程一次:

pigeon_pos = (p1x, p1y)
run = True

def pigeon_spawn():
    global pigeon_pos
    while run:
        pigeon_pos = random.choice([(p1x, p1y), (p2x, p2y), (p3x, p3y)])
        print(pigeon_pos)
        time.sleep(5)

#Puts pigeon_spawn run seperatly
pig = threading.Thread(target=pigeon_spawn)
#starts pigeon_spawn
pig.start()

while run == True:
    #enables you to quit when you press the x at the top
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
    
    #makes crosshair move with the arrow keys
    keys = pygame.key.get_pressed()
    cx += keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]
    cy += keys[pygame.K_DOWN] - keys[pygame.K_UP]

    #imputs background and crosshair
    screen.blit(Background, (0,0))
    screen.blit(Crosshair, (cx, cy))
    screen.blit(Pigeon, pigeon_pos)
    pygame.display.update()

相关问题 更多 >

    热门问题