繁体   English   中英

这个接口是线程安全的吗?

[英]Is this interface thread-safe?

我想做一个控制回路接口。

它具有should_stop()方法来检查循环是否应该中断或继续。

它确实侦听SIGINT信号(Ctrl + C),并且在获得信号后, should_stop()方法将返回True。

现在看来此接口正在工作。

但是我不确定该接口是否是线程安全的。

LoopInterface.h文件

#include "signal.h"
#include "pthread.h"

#define LOCK(mutex)     pthread_mutex_lock(&mutex)
#define UNLOCK(mutex)   pthread_mutex_unlock(&mutex)

class LoopInterface {
public:
    LoopInterface(){
        LOCK(_lock_is_signal_registered);
        bool temp = _is_signal_registered;
        UNLOCK(_lock_is_signal_registered);
        if(!temp)
        {
            register_signal();
        }
    }

    bool should_stop()
    {
        LOCK(_lock_should_stop);
        bool temp = _should_stop;
        UNLOCK(_lock_should_stop);
        return _should_stop;
    }

private:

    static void register_signal()
    {
        LOCK(_lock_is_signal_registered);
        _is_signal_registered = true;
        UNLOCK(_lock_is_signal_registered);

        signal(SIGINT, &LoopInterface::signal_handler);
    }

    static void signal_handler(int sig){
        LOCK(_lock_should_stop);
        _should_stop = true;
        UNLOCK(_lock_should_stop);
    }

    static bool _should_stop;
    static bool _is_signal_registered;
    static pthread_mutex_t _lock_should_stop, _lock_is_signal_registered;
};

LoopInterface.cpp文件

#include "LoopInterface.h"
bool LoopInterface::_should_stop = false;
bool LoopInterface::_is_signal_registered = false;
pthread_mutex_t LoopInterface::_lock_should_stop;
pthread_mutex_t LoopInterface::_lock_is_signal_registered;

这就是它的用法。

/************Threads*************/
#include "LoopInterface.h"
class A : public LoopInterface{

};

void threadX(){
    A a;
    while(!a.should_stop()){
        //do something...
    }
}

你能告诉我这个接口可以线程安全地工作吗? 或不?

如果没有,那是什么问题?


附加问题

我的同步代码还有一个问题。

死锁发生的频率signal_handlershould_stop是因为在should_stop方法锁定同一个mutex锁时,在signal_handler中调用pthread_mutex_lock

而且我找到了一篇文章,指出不应在信号处理程序中调用与线程相关的函数。

我想我应该找到另一种方法来同步我的成员变量。

显然,此代码不是线程安全的:变量_should_stop由某些不受控制的线程中的信号设置,并在运行其自己的线程的LoopInterface读取。 根本没有同步。 仅当只有一个线程时,此方法才是线程安全的。

您可以使用以下命令使代码对线程安全(相对于此特定变量):

static std::atomic<bool> _should_stop;

由于此时您对其他任何值都不感兴趣,因此可以使用std::memory_order_relaxed标志读取变量。

当然,如果从多个线程调用了LoopInterface的构造函数,则当然还需要同步对_is_signal_registered访问。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM