大佬教程收集整理的这篇文章主要介绍了python中的异步,线程问题,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我有以下代码,其中我有一个无限循环,它更新在一个线程中运行的变量的状态,而在另一个线程中,我有一个无限循环,每秒打印所述变量的状态,问题是虽然状态在第一个线程中正确更新,但状态在第二个线程中保持不受影响。
我能做些什么来解决这个问题?我认为使用线程可以解决这个问题,而且我对异步编程不是很精通
在 main.py 中
import cv2 as cv
from utils import WindowCapture
import numpy as np
import os
import time
from threading import Thread
from threading import Event
import pyautogui
from queue import Queue
os.chdir(os.path.dirname(os.path.abspath(__file__)))
wincap = WindowCapture("DragonBallOnline")
global toggle
global enemyState
# >>> pyautogui.mouseDown(); pyautogui.mouseUp() # does the same thing as a left-button mouse click
# >>> pyautogui.mouseDown(button='right') # press the right button down
# >>> pyautogui.mouseUp(button='right',x=100,y=200) # move the mouse to 100,200,then release the right button up.
def targetIsFullHealth(enemy):
return (enemy == np.array([65,27,234])).all()
def targetIsDead(enemy):
return (enemy == np.array([26,10,95])).all()
def targetIsUndefined(enemy):
return (enemy != np.array([65,234])).all() and (enemy != np.array([97,155,146])).all()
def combatLoop(): # unused
## target enemy
## if target is full health attack
## if target is dead wait and loot
## if target is undefined search new target
pass
def bot(): # unused
# DeBUG function not used currently
while True:
##do stuff
Enemylife = wincap.get_screenshot(902,70,120,16)
Items = wincap.get_screenshot(621,163,662,749)
Radar = wincap.get_screenshot(1750,53,157,157)
cv.imshow("Enemylife",EnemylifE)
cv.imshow("Items",Items)
cv.imshow("Radar",Radar)
# print(Enemylife[10][5])
if (Enemylife[10][5] == np.array([65,234])).all():
print("target is full health")
rotatecursor()
elif (Enemylife[10][5] == np.array([97,146])).all():
print("Target is dead")
else:
print("No target")
if cv.waitKey(1) == ord("-"):
cv.destroyAllwindows()
break
print("Done!")
def rotatecursor(): # unused
# pyautogui.mouseDown(button="right")
# pyautogui.mouseUp(button="right",x=10,y=1)
pass
def updateEnemyState(threadName):
global toggle
global enemyState
toggle = True
while True:
Enemylife = wincap.get_screenshot(902,16)
cv.imshow("Enemylife",EnemylifE)
enemy = Enemylife[10][5]
if targetIsDead(enemy):
enemyState = "dead"
elif targetIsFullHealth(enemy):
enemyState = "alive"
else:
enemyState = "undefined"
Event().wait(1.0 / 60)
print("Thread1 :",enemyStatE)
if cv.waitKey(1) == ord("-"):
cv.destroyAllwindows()
toggle = false
break
def macros(threadName):
while toggle:
Event().wait(1.0)
print("Thread2 :",enemyStatE)
if @R_502_4267@ == "__main__":
print("test")
# WindowCapture.List_window_names();
thread1 = Thread(target=updateEnemyState,args=("Thread-1",))
thread2 = Thread(target=macros,))
thread1.start()
thread2.start()
thread1.join()
thread2.join()
在 utils.py 中
import numpy as np
import win32gui,win32ui,win32con
class WindowCapture:
# propertIEs
w = 0
h = 0
hwnd = None
cropped_x = 0
cropped_y = 0
offset_x = 0
offset_y = 0
# constructor
def __init__(self,window_name=NonE):
# find the handle for the window we want to capture
if window_name is None:
self.hwnd = win32gui.GetDesktopWindow()
else:
self.hwnd = win32gui.FinDWindow(None,window_Name)
if not self.hwnd:
raise Exception('Window not found: {}'.format(window_Name))
# get the window size
window_rect = win32gui.GetwindowRect(self.hwnd)
self.w = window_rect[2] - window_rect[0]
self.h = window_rect[3] - window_rect[1]
# account for the window border and titlebar and cut them off
#border_pixels = 8
#titlebar_pixels = 30
border_pixels = 0
titlebar_pixels = 0
self.w = self.w - (border_pixels * 2)
self.h = self.h - titlebar_pixels - border_pixels
self.cropped_x = border_pixels
self.cropped_y = titlebar_pixels
# set the cropped coordinates offset so we can translate screenshot
# images into actual screen positions
self.offset_x = window_rect[0] + self.cropped_x
self.offset_y = window_rect[1] + self.cropped_y
def get_screenshot(self,startX=None,startY=None,wIDth=None,height=NonE):
if startX is None : startX = self.cropped_x
if startY is None : startY = self.cropped_y
if wIDth is None : wIDth = self.w
if height is None : height = self.h
# get the window image data
wDC = win32gui.GetwindowDC(self.hwnd)
dcObj = win32ui.CreateDCFromHandle(wDC)
cDC = dcObj.CreateCompatibleDC()
dataBitMap = win32ui.CreateBitmap()
dataBitMap.CreateCompatibleBitmap(dcObj,wIDth,height)
cDC.SELEctObject(dataBitMap)
cDC.bitBlt((0,0),(wIDth,height),dcObj,(startX,startY),win32con.SRCcopY)
# convert the raw data into a format opencv can read
#dataBitMap.SaveBitmapfile(cDC,'deBUG.bR_157_11845@p')
signedIntsArray = dataBitMap.GetBitmapBits(true)
img = np.fromString(signedIntsArray,dtype='uint8')
img.shape = (height,4)
# free resources
dcObj.deleteDC()
cDC.deleteDC()
win32gui.ReleaseDC(self.hwnd,wDC)
win32gui.deleteObject(dataBitMap.GetHandle())
img = img[...,:3]
img = np.ascontiguousarray(img)
return img
@staticmethod
def List_window_names():
def winEnumHandler(hwnd,ctX):
if win32gui.IsWindowVisible(hwnd):
print(hex(hwnd),win32gui.GetwindowText(hwnd))
win32gui.Enumwindows(winEnumHandler,NonE)
# translate a pixel position on a screenshot image to a pixel position on the screen.
# pos = (x,y)
# WARNING: if you move the window being captured after execution is started,this will
# return incorrect coordinates because the window position is only calculated in
# the __init__ constructor.
def get_screen_position(self,pos):
return (pos[0] + self.offset_x,pos[1] + self.offset_y)
我提供了重新创建示例所需的所有代码,尽管最重要的部分是硬编码的,因此它是一个像素检测器,您可能需要使用另一个窗口名称以及另一个像素位置和颜色值
初始和第一个状态变化:
Thread1 : alive
Thread1 : alive
Thread1 : alive
Thread1 : alive
Thread1 : alive
Thread2 : alive
Thread1 : alive
Thread1 : alive
Thread1 : alive
Thread1 : alive
Thread1 : alive
调试信息
Thread1 : dead
Thread1 : dead
Thread1 : dead
Thread1 : dead
Thread2 : alive
Thread1 : dead
Thread1 : dead
Thread1 : dead
Thread1 : dead
Thread1 : dead
Thread1 : dead
Thread2 的敌人状态应该已经死了 我的猜测是,由于某种原因,敌人状态仍然锁定在线程 2 中。
global
语句必须在每个更改 toogle
值的函数中。你不能只包含一次。将该语句移动到 updateEnemyState
中,它应该开始工作。 @H_668_9@macros 函数不需要那个,因为它不会改变值。你可能会修正拼写;应该是 toggle
。
经过反复试验,我发现 time.sleep()
阻塞了线程,还使用了 Threading 中的 Event().wait(1.0)
而不是队列实现,为了简单起见,我认为全局变量是最好的。
以上是大佬教程为你收集整理的python中的异步,线程问题全部内容,希望文章能够帮你解决python中的异步,线程问题所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。