RAII для ресурсов
От: Alexander Pazdnikov  
Дата: 26.05.10 14:36
Оценка:
Здравствуйте, Коллеги.

Прошу совета в решении следующей задачки.
Для ресурсов требуется, чтобы ресурсом в любой момент времени владел и отвечал за освобождение только один объект.
Прошу Вас покритиковать следующий подход к управлению ресурсами. В данном случае понадобилось просто не плодить зомбиков, привожу "хранителя" для процесса pid'a.

class process
{
public:
    process(pid_t pid) : m_pid(pid)
    {
    }
    process(const process& o) : m_pid(-1)
    {
        m_pid = o.m_pid;
        o.free_pid(); // освободим ресурс из источника, из-за этого mutable
    }
    process& operator=(const process& o)
    {
        if (this != &o)
        {
            m_pid = o.m_pid;
            o.free_pid(); // освободим ресурс из источника, из-за этого mutable
        }
        return *this;
    }
    ~process() 
    { 
        if (m_pid > 0)
        {
            waitpid(m_pid, NULL, 0);
        }
    }
    operator bool() const
    {
        return m_pid > 0;
    }
private:
    mutable pid_t m_pid; // СОМНЕВАЮСЬ в правильности подхода
private:
    process();

    void free_pid() const 
    {
        m_pid = -1;
    }
};


использую так
static process spawn_redirect(const char *path, const char * const args[])
{
    ...

    const process child(fork());
    if (child == 0)
    {
        // потомок читает со входа и пишет на выход
        execv(path, (char * const *)args);
        SERR(path << ", " << sys_error());
        exit(0);
    }
    return child;
}

int some_func()
{
    const char * const args[] = { "/usr/bin/ntpdate", "-qz", ipaddr.c_str(), nullptr };
    process child = spawn_redirect(args[0], args, out, in);
    if (!child)
    {
        return ERR_IO;
    }
}


Владеть ресурсом должен только один объект, чтобы можно было передавать его как результат на стеке.


Можно ли запретить передавать его в виде параметра по значению ?
int you_lose_pid(process pid)
{
...
}

int some_func_caller()
{
    const char * const args[] = { "/usr/bin/ntpdate", "-qz", ipaddr.c_str(), nullptr };
    process child = spawn_redirect(args[0], args, out, in);
    if (!child)
    {
        return ERR_IO;
    }

    you_lose_pid(child);  // ресурс "ушел" вместе с параметром на стеке

    if (!child)
    {
    }
}
raii управление ресурсами
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.