Mutex 作为 class 成员使用 pthreads

Mutex as class member using pthreads

我有三个 类,我们称它们为 A、B 和 HardwareDriver。每个 类 都有一个实例。 a 和 b 运行 在两个不同的线程中。他们都通过 HardwareDriver 的实例访问硬件。类似于:

Class A {
... };

Class B {
... };

Class HardwareDriver {
    public:
        int accessHardware();
};

A a;
B b;
HardwareDriver hd;
pthread_t aThread;
pthread_t bThread;

main() {
    pthread_create(&aThread, NULL, &A::startA, &a);
    pthread_create(&bThread, NULL, &B::startB, &b);

    while (...) { };
    return 0;
}

硬件不能同时被a和b访问,所以我需要用互斥量来保护代码。我是多线程的新手,但直觉上我会在 A 和 B 的方法中通过调用方法 hd.accessHardware().

请求硬件访问之前锁定互斥锁。

现在我想知道是否有可能在 hd.accessHardware() 中执行锁定以进行更多封装。这仍然是线程安全的吗?

在 C/C++ 中进行多线程编程时,您应该确保在进行任何 READ or WRITE 操作,可以离开lockfree READONLY datas.

锁操作必须有尽可能小的范围,如果两个对象访问一个资源你需要一个SINGLEsemaphore/mutex,使用两个会使你暴露在危险中deadlocks.

因此,在您的示例中,每次 read/write 任何 class数据。

您不需要锁定本地数据(堆栈分配的局部变量),也不需要锁定 reentrant 方法。

由于您正在编写 C++,而我们是 2017 年,我想您可以使用,并建议您使用 std::threadstd:: mutex 而不是直接使用 pthread。在 Linux 中,C++ 本机线程支持是对 pthreads 的一个微小包装,因此在嵌入式目标中使用它们的开销也可以忽略不计。

是的,您可以在 HardwareDriver class 中有一个互斥体,并且在您的 class 方法中有一个关键部分。它仍然是安全的。请记住,如果您复制对象,您还将拥有互斥量的副本。

I would lock the mutex in the method of A and B right before it requests the hardware access by calling the method hd.accessHardware().

这会产生在调用 hd.accessHardware() 之前忘记锁定该互斥量的风险。

Now I'm wondering if it's possible, to perform the locking in hd.accessHardware() for more encapsulation. Would this still be thread safe?

这消除了忘记锁定该互斥锁的风险,并使您的 API 更难被滥用。这仍然是线程安全的。