线程资源共享

时间:2010-03-23 14:53:02

标签: multithreading resources mutex sharing

我正在努力进行多线程编程......

我有一个应用程序通过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中执行。

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

谢谢, 大卫

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

首先,重新阅读有关心跳的规格。它是否说每秒必须接收一个实际的心跳消息,或者是否必须每秒接收某些消息,并且如果没有其他消息在飞行中则应该使用心跳?信道上数据的存在是事实证明通信信道是活的,因此不需要特定的心跳消息。

如果需要实际的心跳消息,并且每秒都需要它,在上面的代码中应该只有一个互斥锁,并且两个线程都需要共享它。写入的代码创建了两个独立的互斥锁,因此实际上都不会阻塞。你最终会在频道上发生碰撞而CanBusApi会发生坏事。使MainMutex可见为全局/类变量,并让两个线程都引用它。

相关问题