Случайная запись файла

Если у меня есть несколько потоков, генерирующих блоки файла, каков наилучший способ выписать блоки?

пример) 5 потоков, работающих с файлом из 500 блоков, блок 0 не обязательно завершается до блока 1, но выходной файл на диске должен быть в порядке. (блок 0, блок 1, блок 2, …. блок 499)

программа находится на C ++, может fwrite () как-то «произвольно получить доступ» к файлу? файл создается с нуля, то есть, когда блок 5 завершен, файл все еще может иметь размер 0, поскольку блоки 1 ~ 4 еще не завершены. Могу ли я напрямую выписать блок 5? (с правильным fseek)

Этот фрагмент кода критичен к производительности, поэтому мне действительно интересно все, что может улучшить производительность. Это похоже на сценарий с несколькими производителями (блочными генераторами) и одним потребителем (выходным устройством записи). Идея состоит в том, что поток A может продолжать генерировать следующий блок, когда он завершит предыдущий.

если fwrite может быть «случайным», то средство записи вывода может просто принимать выходные данные, искать и затем записывать. Однако не уверен, что эта конструкция может хорошо работать в больших масштабах.

Некоторые ограничения

  • Каждый блок имеет одинаковый размер, сгенерированный в памяти
  • Размер блока известен заранее, но не общее количество блоков.
  • общий размер составляет несколько ГБ. Большой.
  • На одном сервере может выполняться несколько заданий. каждая работа описана выше. У них есть свои независимые генераторы / писатели, процессы различия.
  • Сервер является машиной Linux / CentOS.

4

Решение

Предполагая, что каждый блок имеет одинаковый размер, и что блоки генерируются в памяти до того, как их требуется записать на диск, тогда получается комбинация lseek а также write было бы прекрасно.

Если вы сможете записать весь блок за одну запись, вы не получите никакого преимущества в использовании fwrite — поэтому просто используйте запись напрямую — однако вам понадобится какой-то блокирующий контроль доступа (мьютекс), если все потоки совместно используют то же самое fd — поскольку поиск + запись не может быть сделан атомарно, и вы не хотели бы, чтобы один поток выполнял поиск до того, как второй поток собирается написать.

Это также предполагает, что ваша файловая система является стандартной файловой системой, а не какой-то экзотической природы, поскольку не все устройства ввода / вывода, которые поддерживает все lseek (например труба).

Обновление: lseek может искать за концом файла, просто установите параметр wherece = SEEK_SET и смещение в абсолютную позицию в файле (fseek имеет такую ​​же опцию, но я никогда не использовал).

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]