2014-10-10 90 views
0

我有一个蓝牙通信线程连续更新的全局缓冲区(uint8_t dataBuffer [])。在任何时候,我的主程序线程都可以访问这个相同的数据缓冲区。问题是如何防止主线程访问缓冲区,而其他线程正在更新它,反之亦然?std ::线程和std ::互斥问题

此刻,我的蓝牙线程在缓冲区更新周围执行互斥锁()和解锁()。当我访问数据时,我的主线程还有另一个互斥锁()和unlock(),但这似乎无法正常工作。出于某种原因,我不断收到很多校验和错误,我很肯定来自线程问题,因为我有另一个单线程测试应用程序,它几乎完美地与同一设备进行通信。

这是削减什么,我在我的通信线程做版本:

uint8_t dbuf[14]; 
while(1) 
{ 
    if(!run) 
     break; 

    // Read data... // 

    mtx1.lock(); 
    memcpy(dataBuffer, dbuf, 14); 
    mtx1.unlock(); 
} 

而在我的主线程我有这样的事情:

mtx2.lock(); 
// Do something with dataBuffer 
mtx2.unlock(); 

有什么根本性的错误是什么我正在做?

+1

您正在使用['std :: mutex'](http://en.cppreference.com/w/cpp/thread/mutex)不正确。你想创建一个互斥体并跨线程共享。 ['std :: lock_guard'](http://en.cppreference.com/w/cpp/thread/lock_guard)是锁定互斥锁的RAII安全方式,如果你想使用它的话。 – Jason 2014-10-10 23:11:41

回答

1

很难说,但听起来好像您使用两个互斥体来保护一块数据。这是行不通的。我们想要一个互斥量。

让我们看一个完整的例子:

#include <thread> 

std::mutex mutex; 
int treasure; 

void worker(int value) { 
    while(true) { 
     std::lock_guard<std::mutex> lock(mutex); 
     treasure = value; 
    } 
} 

int main() { 
    auto t1 = std::thread(worker, 4); 
    auto t2 = std::thread(worker, 5); 

    t1.join(); 
    t2.join(); 
} 

注意事项:

  1. std::mutex在两个线程之间共享。
  2. 每个线程在想要访问共享数据时都使用std::lock_guard。您也可以使用std::unique_lock
+0

感谢您的答案和示例!在线程中执行互斥锁时,是否会阻止主线程访问共享数据? – kbrown 2014-10-10 23:30:34

+1

主线程就像't1'和't2'线程。所以如果它也使用'lock_guard',那就没问题了。 – 2014-10-11 01:33:33

+0

好的。感谢您的澄清。我原本只有一个互斥体,并且正在我的线程和主线程中使用它,但它并未改变通信错误,所以我开始认为它可能还有其他一些问题。回到调试.. :) – kbrown 2014-10-11 19:35:53