Если у меня есть несколько потоков, генерирующих блоки файла, каков наилучший способ выписать блоки?
пример) 5 потоков, работающих с файлом из 500 блоков, блок 0 не обязательно завершается до блока 1, но выходной файл на диске должен быть в порядке. (блок 0, блок 1, блок 2, …. блок 499)
программа находится на C ++, может fwrite () как-то «произвольно получить доступ» к файлу? файл создается с нуля, то есть, когда блок 5 завершен, файл все еще может иметь размер 0, поскольку блоки 1 ~ 4 еще не завершены. Могу ли я напрямую выписать блок 5? (с правильным fseek)
Этот фрагмент кода критичен к производительности, поэтому мне действительно интересно все, что может улучшить производительность. Это похоже на сценарий с несколькими производителями (блочными генераторами) и одним потребителем (выходным устройством записи). Идея состоит в том, что поток A может продолжать генерировать следующий блок, когда он завершит предыдущий.
если fwrite может быть «случайным», то средство записи вывода может просто принимать выходные данные, искать и затем записывать. Однако не уверен, что эта конструкция может хорошо работать в больших масштабах.
Некоторые ограничения
Предполагая, что каждый блок имеет одинаковый размер, и что блоки генерируются в памяти до того, как их требуется записать на диск, тогда получается комбинация lseek
а также write
было бы прекрасно.
Если вы сможете записать весь блок за одну запись, вы не получите никакого преимущества в использовании fwrite — поэтому просто используйте запись напрямую — однако вам понадобится какой-то блокирующий контроль доступа (мьютекс), если все потоки совместно используют то же самое fd — поскольку поиск + запись не может быть сделан атомарно, и вы не хотели бы, чтобы один поток выполнял поиск до того, как второй поток собирается написать.
Это также предполагает, что ваша файловая система является стандартной файловой системой, а не какой-то экзотической природы, поскольку не все устройства ввода / вывода, которые поддерживает все lseek
(например труба).
Обновление: lseek может искать за концом файла, просто установите параметр wherece = SEEK_SET и смещение в абсолютную позицию в файле (fseek имеет такую же опцию, но я никогда не использовал).
Других решений пока нет …