在我的线程/原子值代码中找不到错误

时间:2019-04-16 06:24:01

标签: c++ multithreading atomic

我正在将CodeBlocks与MinGW编译器和wxWidgets库一起使用。

我正在编写一个程序,该程序通过发送消息(使用索引和子索引)并获取带有所述数据的响应消息来从微控制器读取一些数据。

我的计划是一一发送消息,然后使用__atomic int variables__等待响应消息,以检查何时收到响应消息。

这是我发送消息的功能:

typedef std::chrono::high_resolution_clock Clock;
void sendSDO(int index, int subindex)
{
    int nSent = 0;

    atomic_index.store(index);
    atomic_subindex.store(subindex);

    canOpenClient->SDORead(index, subindex);
    auto start = Clock::now();
    nSentMessages++;
    nSent++;
    Sleep(10);

    while ((atomic_index.load() != 0) && (atomic_subindex.load() != 0))
    {
        auto t = chrono::duration_cast<chrono::milliseconds>(Clock::now() - start);
        if(t.count() > 20)
        {
            if (nSent > 5)
            {
                MainFrame->printTxt("[LOG] response not received\n");
                return;
            }
            atomic_index.store(index);
            atomic_subindex.store(subindex);
            canOpenClient->SDORead(index, subindex);
            nSentMessages++;
            nSent++;
            start = Clock::now();
        }
    }
}

将伪代码设置为原子整数,以其要从微控制器读取的所需值的索引和子索引,然后向其发送消息SDORead(),如果在20毫秒内未收到响应,请再次发送该消息,最多5次。

对于接收消息,我有一个带有回调函数的__separate thread__,当我从控制器收到响应消息时会调用该函数:

void notifyEvent(unsigned char ev_type)
{
    SDO_msg_t msg;
    msg = canOpenClient->Cmd_CustomMessageGet(); //get response message

    if(ev_type == CO_EVENT_SDO_READ)
    {
        if ((msg.index == atomic_index.load()) && (msg.subindex == atomic_subindex.load()))
        {
            //does stuff, like saves message data to set container

            atomic_index.store(0);
            atomic_subindex.store(0);
        }
    }
    if (message data not in container)
        printf("not in container!")
}

这里,当收到正确的响应消息时,将相同的atomic int值设置为0,并保存响应消息数据

我还有变量nSentMessagesnReceivedMessages,它们保存已发送消息和已接收消息的数量。最后,我检查这些值是否相同。通常,我不需要(因为我等待每个响应),所以我把它放在那里是一种额外的安全措施。

现在解决问题:

1)我的问题出在回调函数notifyEvent()中,我大概在其中将响应消息数据保存到容器中,但是有时我仍然会“不在容器中!”从那if语句,我不知道为什么。 (我的容器只是普通集set<EDSobject, cmp> container,它不是原子的,也不是任何东西,因为我知道不会同时从不同的线程对其进行读/写。)

2)如果您检查我的功能sendSDO(),则一行Sleep(10)。该程序可以正常运行,但是如果删除它,则该程序将为nSentMessagesnReceivedMessages返回一个不同的值-576和575。每次我运行该程序时都会发生这种情况,但我不理解为什么。

0 个答案:

没有答案