求教一个百度的面试题,关于多线程单例模式的? - 知乎 - c++ - 2

正好前一段时间看了一本多线程的教材,看我现学现卖。

多线程的单例问题非常类似consensus问题:一堆进程进入,退出时的状态必须是第一个进入之后的初始化过的状态。那么用原子操作应当很容易实现。随便想了一下,用两个原子计数,一个表示对象是不是ready,另一个表示是不是正在初始化:

if (fetch(obj_ready))
{
    return obj;
}
else
{
    // 如果没有人在构建,就去构建
    if (fetch_and_set(obj_under_build,true) == false)
    {
        obj = new obj();
        set(obj_ready, true);
        return obj;
    }
    // 否则退出
    else
    {
        return nullptr;
    }
}

即使不用锁,也必然有某种排它机制,因为对象正在初始化的时候是不可用的。这时候如果又有人来访问它,要么让访问者等待,要么把访问者踹出去。

================================================

其实一个标记就够了,obj指针是否为空本身就是状态:

template<typename T>
class SingletonBase
{
public:
    T* get_instance()
    {
        // early out
        if (obj)
            return obj;

        // lock
        while (!atomic_compare_set(&lock, 0, 1))
            yield();

        if (!obj)
        {
            // only first thread would get here
            T* tmp = new T();
            atomic_set(&obj, tmp);
        }

        // unlock
        while (!atomic_compare_set(&lock, 1, 0))
            yield();

        return obj;
    }

    void release_instance()
    {
        // early out
        if (!obj)
            return;

        // only first thread can get non-null
        T* my_obj = atomic_fetch_set(&obj, nullptr);
        if (my_obj)
            delete my_obj;
    }

private:
    T* obj;
    int lock;
};

原网址: 访问
创建于: 2022-10-13 10:31:33
目录: default
标签: 无

请先后发表评论
  • 最新评论
  • 总共0条评论