потокобезопасность системных вызовов read / pread - PullRequest
8 голосов
/ 11 марта 2011

У меня есть несколько запросов, связанных с системными вызовами read () / pread () в многопоточной среде

Я использую Mac-OSX на основе freeBsd, если это помогает каким-либо образом, я использую только этофайл в режиме чтения, а не для чтения / записи. И язык c / c ++

Предположим, у нас есть файл на диске AAAABBBBCCCCDDDEEEE ....

и 4 алфавита помещаются на одной страницеfile

Итак, Page1: AAAA

Page2: BBBB ..... и т. д.

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

read (fd, buff, sizeof (page));

от manНа странице мне дано понять, что чтение также увеличивает указатель файла, поэтому определенно я получу искаженные ответы, такие как

ABCC ABBB .. и т. д. (без определенной последовательности)

, чтобы исправить этоя могу использовать pread ()

"Pread () выполняет ту же функцию, но читаетиз указанной позиции в файле без изменения указателя файла "// с man-страниц

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

Все мои данные выровнены по страницам, и я хочу прочитать по одной странице из каждой темы, например

Тема 1 читает: AAAAТема 2 читает: BBBB Тема 3 читает: CCCC ... фактически не искажая содержимое ..

Я также нашел сообщение Безопасно ли читать () из файла, как только write ()возвращает?

, но это было не совсем полезно.

Я также не уверен, действительно ли у read () будет проблема, о которой я думаю. Файл, который я читаюэто бинарный файл и, следовательно, я немного трудно просто быстро прочитать и проверить вручную ..

Любая помощь будет оценена

Ответы [ 3 ]

9 голосов
/ 11 марта 2011

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

С другой стороны, pread и pwrite не изменяют позицию в открытом файле.Они были добавлены в POSIX именно для той цели, которую вы хотите: выполнять операции ввода-вывода над одним и тем же открытым файлом из нескольких потоков или процессов без операций, мешающих расположению друг друга.Вы все еще можете столкнуться с некоторыми проблемами при оформлении заказа, если вы смешиваете pread и pwrite (или множественные вызовы к pwrite) с перекрывающимися частями файла, но пока вы этого избегаете, они совершенно безопасныза то, что ты хочешь сделать.

1 голос
/ 11 марта 2011

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

int rc;
struct flock f;
f.l_type = F_RDLCK;  /* or F_WRLCK */
f.l_whence = SEEK_SET;
f.l_start = n;
f.l_len = 1;
while ((rc = fcntl(fd, F_SETLKW, &f)) == -1 && errno = EINTR)
    ;
if (rc == -1)
    perror("fcntl(F_SETLKW)");
else {
    /* do stuff */
    f.l_type = F_UNLCK;
    fcntl(fd, F_SETLK, &f);
}

Допускается одновременная блокировка нескольких считывателей, в то время как одна блокировка записи блокирует все остальные.

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

0 голосов
/ 11 марта 2011

Совместное использование блокировки мьютекса между двумя потоками, включите блокировку в потоке до его чтения и разблокируйте блокировку после завершения правильного чтения. См. pthread_mutex_create, pthread_mutex_lock и pthread_mutex_unlock.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...