Потоки в файле множественного поиска

Я открываю файл:

FILE *fp = fopen("test.txt", "r");

файл выглядит так:

cookie    
monster 
test
...

Я создаю 10 тем pthread_create

Каждый поток будет искать строку внутри файла. Я хочу разбить файл на разделы.

Проблема

Я не хочу читать весь файл в память, потому что файл .txt будет огромным. Так что мой подход - искать. Поэтому я бы дал каждому потоку количество строк для поиска.

Таким образом, Thread1 получает строки с 1 по 50, Thread2 получает строки с 51 по 101, Thread3 получает строки со 102 по 152.

Как мне сказать искать в строке 51, затем в строке 102 и т. д.?

fseek (fp, 51, SEEK_SET); // этого не делает


person Mike John    schedule 10.11.2013    source источник


Ответы (2)


Поскольку каждая строка предположительно имеет разную длину, вы не можете узнать ее позицию в файле, не прочитав сначала все предыдущие строки. Поэтому вам нужно прочитать файл, подсчитывая переводы строки, чтобы узнать смещение байтов каждой строки — если вы решите это сделать, сделайте это до создания потоков, иначе они будут дублировать эту работу.

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

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

person Arkku    schedule 10.11.2013
comment
Позвольте мне дважды проверить с вами. Я мог прочитать весь файл. Каждый раз, когда появляется новая строка, я могу сохранить индекс этой строки. Например: int *index; Затем, просматривая файл, сохраните индекс в моем массиве, а затем используйте его для поиска. - person Mike John; 10.11.2013
comment
@MikeJohn Да, сначала создайте индекс смещений строк, а затем создайте потоки для поиска с использованием этого индекса. - person Arkku; 10.11.2013
comment
Звучит здорово. Какой был бы эффективный способ прочитать целые строки из файла, который вы бы порекомендовали? - person Mike John; 10.11.2013
comment
Может быть, просто fgets с буфером, достаточно большим, чтобы вместить предполагаемую максимальную длину строки, и просто проверить последний символ в буфере для перевода строки. - person Arkku; 10.11.2013
comment
Или просто прочитайте байт за байтом, ОС, вероятно, все равно буферизует его, так что это может быть так же хорошо, если не лучше. Но, тем не менее, я бы предложил разбивать файл по байтам, а не по строкам, тогда вам не нужно будет строить индекс, и работа, вероятно, будет более равномерно разделена. - person Arkku; 10.11.2013

Каждому потоку нужен собственный дескриптор файла. Начать 10 потоков, fopen в каждом потоке, fseek в каждом потоке в соответствии с идентификатором потока и шагом.

person Jonas Bötel    schedule 10.11.2013
comment
Я планировал сделать это, запустить потоки, fopen в каждом, но как мне сказать ему искать правильную позицию? Есть ли способ сказать fseek перейти на новую строку? - person Mike John; 10.11.2013