我正在努力进行多线程编程......
我有一个应用程序通过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或的上下文中执行 HeartBeatThread?它似乎在MainThread中执行。
我做错了什么?还有更好的方法吗?
谢谢, 大卫
答案 0 :(得分:0)
我怀疑CAN总线API是单线程的。它可能会将您的DoHeartBeat()请求从第二个线程封送回主线程。在这种情况下,由于主线程被阻止,因此无法成功。您可以通过两种方式解决这个问题:(1)向主线程发送消息,告诉它做心跳,而不是在第二个线程上执行;或者(2)在主线程上使用计时器进行心跳而不是第二线程。 (我确实认为多线程对于这个特殊问题来说太过分了。)
答案 1 :(得分:0)
首先,重新阅读有关心跳的规格。它是否说每秒必须接收一个实际的心跳消息,或者是否必须每秒接收某些消息,并且如果没有其他消息在飞行中则应该使用心跳?信道上数据的存在是事实证明通信信道是活的,因此不需要特定的心跳消息。
如果需要实际的心跳消息,并且每秒都需要它,在上面的代码中应该只有一个互斥锁,并且两个线程都需要共享它。写入的代码创建了两个独立的互斥锁,因此实际上都不会阻塞。你最终会在频道上发生碰撞而CanBusApi会发生坏事。使MainMutex可见为全局/类变量,并让两个线程都引用它。