2019年4月11日 星期四

Always check info.valid_data flag

DDS底層實作可能不是你想的『有資料進來才會收』
實際上對reader來說任何的訊息都是資料,但對我們user來說,只有當valid_data flag是true才代表實際收到真實的Topic sample
好比說Topic sample的status變化,reader是會受影響的

Problem

如果你有一個reader程式是用ANY STATES又不檢查valid_data
因為你的writer只送一次topic sample,所以你會以為你只會印一次hello
但實際上,當writer呼叫dds_instance_dispose
sample的狀態會變成DDS_NOT_ALIVE_DISPOSED_INSTANCE_STATE
對reader來說,這也是資訊,所以ret 會回傳1
所以你就會再印一次hello
writer
void main(void)
{
    sample.msg = "hello";
    dds_writer(writer,&sample);
    /*
        等3秒後 刪除sample
    */
    dds_sleepfor(DDS_SECS(3));
    dds_instance_dispose(writer,&sample);
}
reader
void main(void)
{
    uint32_t states = DDS_ANY_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ANY_INSTANCE_STATE;
 
 
    while(1) {
        ret = dds_take(reader,samples,MAX_SAMPLES,info,states);
        if (ret > 0) {
            printf("%s\n",samples->msg);
        }
    }
     
}

Solution :

states不要偷懶用ANY
或者檢查valid_data flag
reader
void main(void)
{
    uint32_t states = DDS_ANY_SAMPLE_STATE | DDS_ANY_VIEW_STATE | DDS_ALIVE_INSTANCE_STATE;
 
 
    while(1) {
        ret = dds_take(reader,samples,MAX_SAMPLES,info,states);
        if (ret > 0 && info.valid_data) {
            printf("%s\n",samples->msg);
        }
    }
     
}

延伸問題

第二次印hello的情況,如果改成對sample的記憶體操作 ( 例如 印完hello , 做free 或者dds_return_loan)
可能會有問題

沒有留言:

張貼留言

NoSQL Redis intro

Redis是一個使用ANSI C編寫的開源、支援網路、基於記憶體、可選永續性的鍵值對儲存資料庫。 支援rdb 及aof 兩種儲存方式 From  https://zh.wikipedia.org/wiki/Redis Redis 目前擁有兩種資料...