LINUX.ORG.RU

Shared memory & multithreading


0

0

Всем привет,

Может кто-нибудь подскажет, не могу понять проблему.

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

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

Сейчас использую shared memory System V, чтобы делать все в ядре. Возникает следующая проблема - при работе с одной ниткой проблем нет, а вот при работе большего количества ниток возникает BUG: unable to handle paging request at 0x...

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

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

Собственно вопрос в том, как быть? Может кто-то сталкивался с таким? Любые соображения приветствуются.


> Пытался сделать синхронизацию через семафоры, но не хватило пока времени закончить

Надо чтобы хватило. Ну или не семафоры, а их какой-нибудь аналог типа спинлоков/мутексов.

no-dashi ★★★★★
()

Не понял, ты сделал в одном процессе mmap файла и расшарил его для других?

frey ★★
()

Кстати, sysv shm для процессов вообще-то, у потоков и так одно адресное пространство.

frey ★★
()

Спасибо всем откликнувшимся.

Поясню!

В начальный момент создаю shared memory. Этот момент не так важен.

Далее каждый раз при записи в файл я делаю shmat->свою бработку->shmdt.

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

Поясню еще такой момент, использую shared memory чтобы в дальнейшем usermode приложением получить изменения, не для того чтобы расшарить кусок между потоками.

SteveN
() автор топика
Ответ на: комментарий от SteveN

Мда, понятней не стало.

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

frey ★★
()
Ответ на: комментарий от frey

Прошу прощения за неточности и неясности :)

Я имею в виду следующее - пишу изменения в функции sys_pwrite64, которая находится в ядре (fs/read_write.c).

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

SteveN
() автор топика
Ответ на: комментарий от k0l0b0k

На данном этапе только ради этого.

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

SteveN
() автор топика
Ответ на: комментарий от SteveN

Что-то я окончательно закопался...

Делаю семафор, чтобы зыкрыть работу с shared memory. и каждый раз мне возвращается новый семафор... Почему, ведь IPC_EXCL говорит, что если создан семафор, то вернется ошибка и в этом случае я буду работать с уже существующим семафором...

смотрю ipcs -s - семафор создан.

       int sid;        union semun semopts; semopts.val = 1;        struct sembuf sem_lock;        key_t sem_key=16384;

       if ((sid = sys_semget( sem_key, 1, IPC_CREAT | IPC_EXCL | 0666 )) != -1)        {           sys_semctl(sid, 0, SETVAL, semopts);          printk(KERN_ERR «\nsys_semget create new \n»);        }        else        {          sid = sys_semget( sem_key, 1, 0666 );        }

дальше делаю lock

       sem_lock.sem_num =0;        sem_lock.sem_op =-1;        sem_lock.sem_flg =0;        sys_semop(sid, &sem_lock, 1);

потом unlock

       struct sembuf sem_unlock;        sem_unlock.sem_num =0;        sem_unlock.sem_op = 1;        sem_unlock.sem_flg =0;        sys_semop(sid, &sem_unlock, 1);

SteveN
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.