线程资源共享

发布于 2024-08-25 20:27:33 字数 1064 浏览 8 评论 0原文

我正在努力解决多线程编程问题...

我有一个应用程序通过 CAN 转 USB 与外部设备通信 模块。我已经让应用程序在 CAN 总线上正常通信,但是 应用程序需要传输“心跳” 每秒发一条消息。

这听起来是使用线程的最佳时机,所以我创建了一个线程 每秒都会醒来并发送心跳。我的问题是 有就是共享CAN总线接口。只能发送心跳 当总线空闲时。我如何共享资源?

这是伪代码,显示了我到目前为止所拥有的内容:

TMainThread
{
    Init:
        CanBusApi =new TCanBusApi;
        MutexMain =CreateMutex( "CanBusApiMutexName" );

        HeartbeatThread =new THeartbeatThread( CanBusApi );

    Execution:
        WaitForSingleObject( MutexMain );
        CanBusApi->DoSomething();
        ReleaseMutex( MutexMain );
}

THeartbeatThread( CanBusApi )
{
    Init:
        MutexHeart =CreateMutex( "CanBusApiMutexName" );

    Execution:
        Sleep( 1000 );
        WaitForSingleObject( MutexHeart );
        CanBusApi->DoHeartBeat();
        ReleaseMutex( MutexHeart );
}

我看到的问题是,当调用 DoHeartBeat 时,它会导致 主线程在等待 MutexMain 时按预期阻塞,但是 DoHeartBeat 也停止。 DoHeartBeat 直到之后才完成 WaitForSingleObject(MutexMain) 超时失败。

DoHeartBeat 是在 MainThread 的上下文中执行还是 心跳线程?它似乎是在主线程中执行的。

我做错了什么?有更好的办法吗?

谢谢, 大卫

I'm struggling with multi-threaded programming...

I have an application that talks to an external device via a CAN to USB
module. I've got the application talking on the CAN bus just fine, but
there is a requirement for the application to transmit a "heartbeat"
message every second.

This sounds like a perfect time to use threads, so I created a thread
that wakes up every second and sends the heartbeat. The problem I'm
having is sharing the CAN bus interface. The heartbeat must only be sent
when the bus is idle. How do I share the resource?

Here is pseudo code showing what I have so far:

TMainThread
{
    Init:
        CanBusApi =new TCanBusApi;
        MutexMain =CreateMutex( "CanBusApiMutexName" );

        HeartbeatThread =new THeartbeatThread( CanBusApi );

    Execution:
        WaitForSingleObject( MutexMain );
        CanBusApi->DoSomething();
        ReleaseMutex( MutexMain );
}

THeartbeatThread( CanBusApi )
{
    Init:
        MutexHeart =CreateMutex( "CanBusApiMutexName" );

    Execution:
        Sleep( 1000 );
        WaitForSingleObject( MutexHeart );
        CanBusApi->DoHeartBeat();
        ReleaseMutex( MutexHeart );
}

The problem I'm seeing is that when DoHeartBeat is called, it causes the
main thread to block while waiting for MutexMain as expected, but
DoHeartBeat also stops. DoHeartBeat doesn't complete until after
WaitForSingleObject(MutexMain) times out in failure.

Does DoHeartBeat execute in the context of the MainThread or
HeartBeatThread? It seems to be executing in MainThread.

What am I doing wrong? Is there a better way?

Thanks,
David

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

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

发布评论

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

评论(2

肥爪爪 2024-09-01 20:27:33

我怀疑 CAN 总线 API 在幕后是单线程的。它可能会将您的 DoHeartBeat() 请求从第二个线程编组回主线程。在这种情况下,由于主线程被阻塞,它就无法成功。您基本上可以通过两种方式解决此问题:(1)向主线程发送消息,告诉它进行心跳,而不是在第二个线程上进行;或者 (2) 在主线程上使用计时器而不是第二个线程来记录心跳。 (我确实认为多线程对于这个特定问题来说太过分了。)

I suspect that the CAN bus API is single-threaded under the covers. It may be marshaling your DoHeartBeat() request from your second thread back to the main thread. In that case, there would be no way for it to succeed since your main thread is blocked. You can fix this in basically two ways: (1) send a message to the main thread, telling it to do the heart beat, rather than doing it on the second thread; or (2) use a timer on the main thread for your heart beat instead of a second thread. (I do think that multithreading is overkill for this particular problem.)

云之铃。 2024-09-01 20:27:33

首先,重新阅读有关心跳的规范。它是否表示必须每秒接收一条实际的心跳消息,或者是否有必要每秒接收一些消息,并且如果没有其他消息正在传输,则应使用心跳?通道上数据的存在实际上是通信通道处于活动状态的证据,因此不需要特定的心跳消息。

如果需要实际的心跳消息,并且每秒都需要,那么在上面的代码中应该只有一个互斥体,并且两个线程需要共享它。编写的代码创建了两个单独的互斥体,因此实际上两者都不会阻塞。您最终会在通道上发生冲突,并且 CanBusApi 中会发生不好的事情。使 MainMutex 成为可见的全局/类变量,并让两个线程都引用它。

First, re-read the specs about the heartbeat. Does it say that an actual heartbeat message must be received every second, or is it necessary that some message be received every second, and that a heartbeat should be used if no other messages are in flight? The presence of data on the channel is de-facto evidence that the communications channel is alive, so no specific heartbeat message should be required.

If an actual heartbeat message is required, and it's required every second, in the above code there should be only one mutex and both threads need to share it. The code as written creates two separate mutexes, so neither will actually block. You'll end up with a collision on the channel and Bad Things Will Happen in CanBusApi. Make MainMutex visible a global/class variable and have both threads reference it.

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