python螺纹卡住

发布于 2025-01-28 02:33:54 字数 2825 浏览 2 评论 0原文

我正在尝试从一个称为 cameraprocessing 的线程切换到一个称为 serverkeypoints 和viceversa的线程。 确切地说, cameraprocessing 更改了一个全局变量,称为 value serverkeypoints 通过通过WebSocket发送给客户端来消耗全局值。为了保护全局变量,我使用了条件机制

我有两个问题:

  1. 在某个时刻,脚本卡住了,线程不向前走。Websocket
  2. 客户端未接收通过WebSocket发送的数据,

这两个线程位于一个名为 main_server.py.py (我知道这不是最好的主意,最好将这些线程拆分在不同的文件中)。

main_server.py

import threading
import asyncio
import websockets
condition = threading.Condition()
VALUE = 0
FLAG = 0


class ServerKeypoints(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    async def communicate(self, websocket):
        global VALUE
        global FLAG

        while True:
            condition.acquire()
            if FLAG == 1:
                FLAG = 0
                print(f"SERVER VAL: {VALUE}")
                await websocket.send(f"{VALUE}")
                condition.notify_all()
            else:
                condition.wait()
            condition.release()

    async def main(self,):
        async with websockets.serve(self.communicate, "localhost", 9998):
            await asyncio.Future()  # run forever

    def run(self):
        asyncio.run(self.main())



class CameraProcessing(threading.Thread):
    def __init__(self) -> None:
        threading.Thread.__init__(self)
    
    def run(self):
        global VALUE
        global FLAG

        while True:
            condition.acquire()
            if FLAG == 0:
                VALUE += 1
                print(f"CAMERA VAL: {VALUE}")
                FLAG = 1
                condition.notify_all()
            else:
                condition.wait()
            condition.release()

client.py 是按照以下方式编写的:

import websocket

def on_message(wsapp, message):
    message = message
    print(message)

wsapp = websocket.WebSocketApp("ws://localhost:9998", on_message=on_message)
while True:
    wsapp.run_forever()

在Visual Studio Code终端中,我有这样的结果:

CAMERA VAL: 20301
SERVER VAL: 20301
CAMERA VAL: 20302
SERVER VAL: 20302
CAMERA VAL: 20303
SERVER VAL: 20303
CAMERA VAL: 20304
SERVER VAL: 20304
CAMERA VAL: 20305
SERVER VAL: 20305
CAMERA VAL: 20306
SERVER VAL: 20306
CAMERA VAL: 20307
SERVER VAL: 20307
CAMERA VAL: 20308
SERVER VAL: 20308
CAMERA VAL: 20309
SERVER VAL: 20309
CAMERA VAL: 20310
SERVER VAL: 20310
CAMERA VAL: 20311
SERVER VAL: 20311
CAMERA VAL: 20312
SERVER VAL: 20312
CAMERA VAL: 20313
SERVER VAL: 20313

但是它不会前进。

I'm trying to switch from one thread called CameraProcessing to another thread called ServerKeypoints and viceversa.
To be precise, CameraProcessing changes a global variable called VALUE while ServerKeypoints consumes the global value by sending it via websocket to a client. To protect the global variable I've used the Condition mechanism.

I have two problems:

  1. At a certain moment the script stucks, the threads don't go forward
  2. The websocket client doesn't receive the data sent via websocket

The two threads are located in a script called main_server.py (I know that it is not the best idea and that it would be better to split these threads in different files).

main_server.py

import threading
import asyncio
import websockets
condition = threading.Condition()
VALUE = 0
FLAG = 0


class ServerKeypoints(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)

    async def communicate(self, websocket):
        global VALUE
        global FLAG

        while True:
            condition.acquire()
            if FLAG == 1:
                FLAG = 0
                print(f"SERVER VAL: {VALUE}")
                await websocket.send(f"{VALUE}")
                condition.notify_all()
            else:
                condition.wait()
            condition.release()

    async def main(self,):
        async with websockets.serve(self.communicate, "localhost", 9998):
            await asyncio.Future()  # run forever

    def run(self):
        asyncio.run(self.main())



class CameraProcessing(threading.Thread):
    def __init__(self) -> None:
        threading.Thread.__init__(self)
    
    def run(self):
        global VALUE
        global FLAG

        while True:
            condition.acquire()
            if FLAG == 0:
                VALUE += 1
                print(f"CAMERA VAL: {VALUE}")
                FLAG = 1
                condition.notify_all()
            else:
                condition.wait()
            condition.release()

While client.py is written in the following way:

import websocket

def on_message(wsapp, message):
    message = message
    print(message)

wsapp = websocket.WebSocketApp("ws://localhost:9998", on_message=on_message)
while True:
    wsapp.run_forever()

In the Visual Studio Code terminal I have a result like this:

CAMERA VAL: 20301
SERVER VAL: 20301
CAMERA VAL: 20302
SERVER VAL: 20302
CAMERA VAL: 20303
SERVER VAL: 20303
CAMERA VAL: 20304
SERVER VAL: 20304
CAMERA VAL: 20305
SERVER VAL: 20305
CAMERA VAL: 20306
SERVER VAL: 20306
CAMERA VAL: 20307
SERVER VAL: 20307
CAMERA VAL: 20308
SERVER VAL: 20308
CAMERA VAL: 20309
SERVER VAL: 20309
CAMERA VAL: 20310
SERVER VAL: 20310
CAMERA VAL: 20311
SERVER VAL: 20311
CAMERA VAL: 20312
SERVER VAL: 20312
CAMERA VAL: 20313
SERVER VAL: 20313

But it does not go forward.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

临风闻羌笛 2025-02-04 02:33:54

正如Michal Butscher在评论中所建议的那样,我再次尝试了由 WebSockets提供的客户端脚本 模块,并且我已经通过以下方式进行了修改:

import asyncio
import websockets

async def receive():
    while True:
        try:
            async with websockets.connect("ws://localhost:9998", ping_interval=None) as websocket:
                msg = await websocket.recv()
                print(f"{msg}")
        except:
            continue

if __name__ == "__main__":
    asyncio.run(receive())

现在它不了t卡住。

我知道组合 async thread 不是一个好主意,但是如果您有替代方案,我将很高兴阅读它们。

As suggested by Michal Butscher in the comments, I've tried again the client script provided by the websockets module and I've modified in the following way:

import asyncio
import websockets

async def receive():
    while True:
        try:
            async with websockets.connect("ws://localhost:9998", ping_interval=None) as websocket:
                msg = await websocket.recv()
                print(f"{msg}")
        except:
            continue

if __name__ == "__main__":
    asyncio.run(receive())

Now it doesn't stuck.

I know that the combination async and thread is not a good idea but if you have alternatives to propose I will be glad to read them.

天暗了我发光 2025-02-04 02:33:54

我使用了线程,因为它们共享全局变量值,并且为了保护它,我使用条件等线程锁。

好的,但是您不需要创建线程即可使用全局变量。您的serverkeypoints线程和您的cameraprocessing线程永远不会同时执行任何有趣的事情,那么为什么不只是一个这样做的一个线程呢?

async def communicate(self, websocket):
    global VALUE

    while True:
        VALUE += 1
        print(f"CAMERA VAL: {VALUE}")
        print(f"SERVER VAL: {VALUE}")
        await websocket.send(f"{VALUE}")

摆脱条件,摆脱flag,摆脱线程。这要简单得多,而且(我很确定)它将执行与您的示例代码相同的事情。

I've used threads because they share the global variable VALUE and in order to protect it I use thread locks like Condition.

OK, but you don't need to create threads in order to use global variables. Your ServerKeypoints thread and your CameraProcessing thread never do any interesting thing concurrently with each other, so why not just have one thread that does this?

async def communicate(self, websocket):
    global VALUE

    while True:
        VALUE += 1
        print(f"CAMERA VAL: {VALUE}")
        print(f"SERVER VAL: {VALUE}")
        await websocket.send(f"{VALUE}")

Get rid of the condition, get rid of the FLAG, get rid of the threads. It's a whole lot simpler, and (I'm pretty sure) it will do the same as what your example code does.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文