Если вы открыты для использования boost, то я предлагаю вам использовать класс file_lock. Это означает, что вы хотите сохранить имя файла для файлов, которые вы открываете/закрываете, потому что fstream не делает этого для вас.
Они имеют два режима lock()
, которые можно использовать для записи (то есть только один такой замка на время совместного использования блокировки предотвращает блокировку тоже) и lock_sharable()
, которые вы можете использовать для чтения (т.е. любого количество потоков может получить такое замок).
Обратите внимание, что в конечном итоге вы сочтете это сложным для управления, прочитайте и напишите, таким образом. То есть, если всегда есть кто-то, чтобы прочитать, закрываемый замок никогда не может быть освобожден. В этом случае эксклюзивный замок никогда не получит шанс взять ....
// add the lock in your class
#include <boost/interprocess/sync/file_lock.hpp>
class my_files
{
...
private:
...
boost::file_lock m_lock;
};
Теперь, когда вы хотите получить доступ к файлу, вы можете заблокировать его так или иначе. Если поток отвечает за это, вы можете добавить функции для доступа пользователя к блокировке. Если реализация функции чтения и записи в my_files отвечают, вы хотите, чтобы получить стек на основе объекта, который блокирует и разблокирует для вас (RAII):
class safe_exclusive_lock
{
public:
safe_exclusive_lock(file_lock & lock)
: m_lock_ref(lock)
{
m_lock_ref.lock();
}
~safe_exclusive_lock()
{
m_lock_ref.unlock();
}
private:
file_lock & m_lock_ref;
};
Теперь вы можете безопасно заблокировать файл (т.е. вы замок, делать то, что может бросить, вы всегда разблокировать перед выходом из вашего текущего {} -блок):
ssize_t my_files::read(char *buf, size_t len)
{
safe_exclusive_lock guard(m_lock);
...your read code here...
return len;
} // <- here we get the unlock()
ssize_t my_files::write(char const *buf, size_t len)
{
safe_exclusive_lock guard(m_lock);
...your write code here...
return len;
} // <- here we get the unlock()
file_lock использует файл, так что вы хотите, чтобы файл fstream уже создан, когда создается file_lock , Если файл fstream не может быть создан в конструкторе, вы, вероятно, хотите, чтобы преобразовать переменную m_lock в уникальном указателе:
private:
std::unique_ptr<file_lock> m_lock;
И когда вы ссылаться на него, теперь нужна звездочка:
safe_exclusive_lock guard(*m_lock);
Обратите внимание, что в целях безопасности, вы должны проверить, является ли указатель действительно выделяется, если не определено, это означает, что файл еще не открыт, так что я хотел бы предложить вам бросить:
if(m_lock)
{
safe_exclusive_lock guard(*m_lock);
...do work here...
}
else
{
throw file_not_open();
}
// here the lock was released so you cannot touch the file anymore
В е е открытое, вы создаете замок:
bool open(std::string const & filename)
{
m_stream.open(...);
...make sure it worked...
m_lock.reset(new file_lock(filename));
// TODO: you may want a try/catch around the m_lock and
// close the m_stream if it fails or use a local
// variable and swap() on success...
return true;
}
И не забудьте освободить объект блокировки в ваших близких:
void close()
{
m_lock.reset();
}
материал Такой низкоуровневый лучше всего сделано в C, с минимальными накладными расходами как возможно ... –
@ bash.d Чепуха, почему вы так думаете? Весь смысл C++ заключается в предоставлении абстракций с надбавкой. Я заставил тебя привязаться к кому-то, кто знал это. –
@KonradRudolph Я не знаю о вас, но я не знаю о многих файловых системах, реализованных на C++ ... –