LINUX.ORG.RU

Как заставить проги обращатся к одному файлу по очереди???


0

0

Ведь если шедулер переключится на другую прогу когда первая не сняла флаг(блокировку) то вторая не получит доступа к файлу. А если вставить nanosleep() в цикле обращения к файлу то работать будет слишком медленно.

Также пытался юзать sched_yield() но ничего понятного не вышло???

★★★★★
Ответ на: комментарий от dilmah

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

cvv ★★★★★
() автор топика

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

как это не в состоянии? очень даже "вклинится", но
переключение будет не в каждой итерации, а после того,
как у активного процесса кончится timeslice, или если
у ждущего будет больший приоритет.

если хотите, чтобы переключалось чаще - yield() после
снятия блокировки, но лучше не надо.

если нужны _гарантии_ переключения, можно pipe завести,
и обмениваться синхронизирующими собщеними, например.


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

>как это не в состоянии? очень даже "вклинится", но >переключение будет не в каждой итерации, а после того, >как у активного процесса кончится timeslice,

В своих експериментах я часто встречал что в одной проги timeslice постоянно заканчивалось между установкой и снятием блокировки итого второй приходилось долго ждать своей очереди

>если хотите, чтобы переключалось чаще - yield() после >снятия блокировки, но лучше не надо.

Обьясни???

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

> В своих експериментах я часто встречал что в одной проги
> timeslice постоянно заканчивалось между установкой и снятием
... интересно, как это вы определяли ...
> блокировки итого второй приходилось долго ждать своей очереди

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

что значит "долго ждать" ? повторяю, нужны гарантии -
устраивайте синхронизацию сами. flock не гарантирует
fairness, ядро может классифицировать процессы как
non-interactive, что удлинит timeslice, и т.д.

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

> > если хотите, чтобы переключалось чаще - yield()
> Обьясни???

Обьяснить что? 

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

не забудьте, кстати, что "абсолютное" время между переключениями будет еще больше, если процесс, держащий lock занимается i/o или еще чем-то блокирующим.

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

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

Абсолютно полной монополизации действительно не происходит но та временная монополизация которая происходит порядком мешает работе так ресурс интенсивно используется обеими прогами

>> > если хотите, чтобы переключалось чаще - yield()
>> Обьясни???

>Обьяснить что?

Почему нежелательно юзать yield()???

cvv ★★★★★
() автор топика

в словах cvv наверно какой-то пойнт есть.

По моему некомпетентому мнению, чтобы обеспечить этот самый fairness можно дополнительно использовать select c небольшим таймаутом..

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

может быть вспомогательный(е) файл(ы) еще понадобится

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

>По моему некомпетентому мнению, чтобы обеспечить этот самый fairness можно дополнительно использовать select c небольшим таймаутом..

А по подробнее такую идею можна а то я недогадываюсь куда етот select можна засунуть

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

sys_sched_yield() во-первых немного по разному ведет
себя в зависимости от версии ядра. в 2.6 процесс
удаляется из active, и помещается в expired prio_array.
иными словами, он не получит cpu тех пор, пока _все_
runnable процессы не исчерпают свой timeslice.

если в системе кроме этих двух больше ничего не работает,
yield и будет, хм... вроде бы, переключать между ними,
иначе они, в основном, будут спать. 

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

ну например, договариваешься между своими 2 процессами об именах 2-х файлов, наличие которых будет выражать их злобу. /tmp/zloba1 и /tmp/zloba2

Первый процесс перед тем как сделать lockf проверяет наличие файла /tmp/zloba2. Если он есть, он делает select на этом файле ожидая пока его сотрут. Во избежание какой-нибудь фигни, таймаут на селект ставит небольшой. После выхода из селекта процесс создает файл /tmp/zloba1 и делает блокирующий lockf. После выхода из lockf, он стирает /tmp/zloba1.

Второй процесс делает то же самое с заменой zloba1 на zloba2, и zloba2 на zloba1.

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

тока не надо ничего усложнять :))

int parent[2], child[2];

pipe(parent); pipe(child);

write(parent, &c, 1); // первым начнет parrent

После fork() parent делает:

for (;;)
{
        char unused;

        read(parent[0], &unused, 1);

        // чего-то делаем, теперь хотим переключить

        write(child[1], &unused, 1);
}

child наоборот, read(child[0]), write(parent[1]).

можно socket, да по-разному можно.
и забыли про flock().

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

согласен. Но только конкретно так они действительно только строго по очереди. А в варианте с селектом, это необязательно. Он просто старается "чтобы никому не было обидно" сделать.

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

dilmah, ваш вариант со злобами не будет работать.
как вы вообще собираетесь ждать удаления файла
с помощью select() ? да даже и не в этом дело...

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

> как вы вообще собираетесь ждать удаления файла с помощью select()?

согласен. Я селектом никогда раньше не пользовался, так, представление имею.

В любом случае надо иметь, как у вас два пайпа, передавать какие-нибудь символы по пайпам для обозначения нарастания и снятия злобы. И ждать снятия злобы селектом:)

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

> в любом случае надо иметь, как у вас два пайпа

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

for (;;) {
        lock(my_lock);

        // работаем

        unlock(his_lock);
}

другой процесс все наоборот.

еще сигналами можно синхронизироваться.

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

Hi!

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

Подтормаживает но работает!

И попытайтесь сюда прикрутить ТРУБЫ и ЗЛОБЫ.

Чё страшно стало???:-)))

cvv

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