2015-12-22 238 views
0

我正在寻找使用boost进程库的两个线程之间的互连性的正确模式。与使用标准库的典型并行编程不同,我不认为这种库具有特定的功能。 所以我正在寻找一种基本的技术,并了解这些同步原语的用法。使用互斥锁和condition_variables

有两个线程:writer和reader,它们使用共享内存。命名互斥体用于同步访问共享内存中的对象(字符串和向量)。当读取器将数据写入共享内存时,用于等待的条件变量。所以情景是: - 阅读器启动并在具有数据的向量应该为非空的条件下初始化有名互斥体上的条件变量。并等待... - 写入程序锁定互斥体并填充向量 - 写入程序“通知一个”写入数据向量已完成并解锁互斥体 - 读取器接收通知,锁定互斥锁并处理数据向量。

之后,读者应该通知作者阅读已完成,向量可以再次用新的数据部分填满。

所以我不知道如何设置所有这些等待并正确通知。看起来像我的版本是僵局。请指教。

读者的线程代码

namespace bi = boost::interprocess; 
    using bi_char_vector = bi::vector<char, CharAllocator>; 

    bi::named_mutex    mtx{bi::open_or_create, "mtx"}; 
    bi::named_condition   cnd{bi::open_or_create, "cnd"}; 

    data = segment.find_or_construct<bi_char_vector>("data")(segment.get_segment_manager()); 
    while (!done) { 
     bi::scoped_lock<bi::named_mutex> lock{mtx}; 
     cnd.wait(lock, [data] {return !data->empty(); }); 

     // process the data... 

     cnd.notify_one(); 
    } 

作家的线程代码:

bi::managed_shared_memory segment(bi::open_only, shm_name.c_str()); 
    bi::named_mutex mtx{bi::open_only, "mtx"}; 
    bi::named_condition cnd(bi::open_only, "cnd"); 

    data = segment.find_or_construct<bi_char_vector>("data")(segment.get_segment_manager()); 

    for(std::size_t chunk_num = 0; chunk_num < chunk_count; ++chunk_num) { 
     bi::scoped_lock<bi::named_mutex> lock { mtx }; 
     cnd.wait(lock); 
     data->clear(); 
     // fills the data 
     cnd.notify_one(); 
    } 
} 

如果我设置在作家圈的等待,它停止在此, 如果我删除此等待,看起来像阅读器接收和处理上一次循环迭代只有

回答

0

发现问题。 对读者的身边说:

while (!done) { 
    bi::scoped_lock<bi::named_mutex> lock{mtx}; 
    cnd.wait(lock, [data] {return !data->empty(); }); 

    // process the data... 

    data->clear(); 
    cnd.notify_one(); 
} 

对作家方:

for(std::size_t chunk_num = 0; chunk_num < chunk_count; ++chunk_num) { 
     bi::scoped_lock<bi::named_mutex> lock { mtx }; 
     cnd.wait(lock, [data] {return data->empty(); }); 
     //... 
     cnd.notify_one(); 
    } 

,现在它按预期工作