【发布时间】:2018-09-13 13:40:11
【问题描述】:
我正在编写一个从不同线程写入二进制文件的程序。每个线程将写入文件的不同位置。我不使用同步,我的程序正常工作。我想问你我是否应该使用一些同步以及如何或是否足以希望操作系统同步无论如何都会做到这一点。我在 Linux 上,使用 gcc 编译器,但在某些时候它也可能在其他平台上运行。我使用以下函数从不同线程写入文件。
void writeBytesFrom(std::string fileName, uint64_t fromPosition, uint8_t* buffer, int numBytes)
{
if(CHAR_BIT != 8)
{
std::stringstream errMsg;
errMsg << "Can not use this platform since CHAR_BIT size is not 8, namely it is "
<< CHAR_BIT << ".";
LOGE << errMsg.str();
throw std::runtime_error(errMsg.str());
}
std::ofstream file(fileName,
std::ios::binary | std::ios::out
| std::ios::in); // Open binary, for output, for input
if(!file.is_open()) // cannot open file
{
std::stringstream errMsg;
errMsg << "Can not open file " << fileName << ".";
LOGE << errMsg.str();
throw std::runtime_error(errMsg.str());
}
file.seekp(fromPosition); // put pointer
std::streampos cur = file.tellp();
file.write((char*)buffer, numBytes);
auto pos = file.tellp();
auto num = pos - cur;
file.close();
if(num != numBytes)
{
std::stringstream errMsg;
errMsg << num << " bytes written from number of bytess that should be written "
<< numBytes << " to " << fileName << ".";
LOGE << errMsg.str();
throw std::runtime_error(errMsg.str());
}
}
如果您对改进我的代码有任何进一步的建议,我愿意接受。我使用 uint8_t 缓冲区的原因是,我更自然地理解缓冲区表示 8 位字节,而不是使用 unsigned char。我知道有些纯粹主义者可能会反对。
谢谢, 沃伊塔。
【问题讨论】:
-
我认为你的代码是靠运气工作的。 std::basic_filebuf 没有声明通过两个 filebuf 并发访问同一个文件。
-
事实上,你的线程一次只能写入文件,所以最好有一个“写入顺序”队列。您的线程将其数据/位置放入队列,特定线程将负责将数据写入磁盘。
-
只要每个线程打开自己的文件描述符(std::ifstream 对象)并写入文件的不同部分应该没有问题。
标签: c++ synchronization