LINUX.ORG.RU

POSIX: как так можно работать


0

0

Вот из man-a для ualarm:

The interaction of this function with other timer functions such as alarm(2), sleep(3), nanosleep(2), setitimer(2), timer_create(3), timer_delete(3), timer_getoverrun(3), timer_gettime(3), timer_settime(3), usleep(3) is unspecified.

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

Где можно почитать как это все правильно использовать?

★★★★

Особенно хочется иметь одновременно ualarm и nanosleep.

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

> Вот из man-a для ualarm:

Ты не на то внимание обращаешь. ВотЪ: "This function is obsolete. Use setitimer(2) or POSIX interval timers (timer_create(3), etc.) instead."

Наверное, ualarm мог реализовываться на setitimer, timer_* или прочих, поэтому unspecified.

> То-есть они все несовместимы между собой.

А это ты откуда взял? У меня маны на setitimer и timer_create ничего такого не говорят.

> Где можно почитать как это все правильно использовать?

ХЗ. Надо использовать что-нибудь одно, и это одно - timer_* :) Всё остальное - исторический багаж.

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

> ХЗ. Надо использовать что-нибудь одно, и это одно - timer_* :) Всё остальное - исторический багаж.

Хорошо, но если мне нужно сделать задержку на 1 секунду скажем, мне что городить огород из таймеров?

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

> но если мне нужно сделать задержку на 1 секунду скажем, мне что городить огород из таймеров?

Если это единственное, что тебе нужно, используй sleep :) timer_* - это для более сложных случаев, когда нужно отслеживать тайм-ауты и т.д.

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

> Если это единственное, что тебе нужно, используй sleep :) timer_* - это для более сложных случаев, когда нужно отслеживать тайм-ауты и т.д.

Нужно одновременно 3 вещи:

1. Периодически тикающий таймер.
2. Возможность в произвольных местах делать задержку от сотен мкс до десятков секунд.
3. Посылать/обрабатывать сигналы.

1+3  - не проблема, но второе при этом становится очень загадочным.

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

Предлогается по таймеру увеличивать счетчик, а дадержку делать на базе этого счетчика? Или я что-то упускаю?

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

> Предлогается по таймеру увеличивать счетчик, а дадержку делать на базе этого счетчика?

Ну можно и так, но зачем? Сделай функцию deepsleep: в начале получаешь текущее время, вызываешь nanosleep, если она вернула EINTR - вычисляешь оставшееся время и ждешь его.

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

Я так и сделал, просто видимо не правильно восприянл вот это:

> ХЗ. Надо использовать что-нибудь одно, и это одно - timer_* :) Всё остальное - исторический багаж.

Если использовать nanosleep() - это нормально, то все OK.

А вообще чего-то действительно бардака много.

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

И еще по-ходу дела вопрос:

Для функций принимающих указатели на структуры можно-ли как-то узнать, нужно сохранять содержимое этой структуры после вызова функции или нет?

Например sigevent для timer_create(). Из man-a этого непонятно.

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

timer_* может генерить не SIGALRM, а указанный сигнал. Тогда таймер своим тиканием не будет смущать других, кто использует этот же сигнал. Чтобы сигналы от таймера не прерывали nanosleep или ещё кого, надо поставить флажок SA_RESTART в sigaction.

С таймером можно ещё так работать: заблокировать SIGALRM, соорудить таймер и запустить цикл с sigwait.

Все функции, кроме timer_* и nanosleep - по сути устаревшие, на них можно забить. Только не все оси умеют таймеры :/

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

> Для функций принимающих указатели на структуры можно-ли как-то узнать, нужно сохранять содержимое этой структуры после вызова функции или нет?

Не нужно.

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

Я сделал таймер с sigev_notify = SIGEV_THREAD; и теперь все хорошо - он при срабатывпнии просто вызывает функцию.

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

> Сильно по ресурсам затратно?

Понятия не имею. Тебе судить :)

> Ok, верну сигналы :)

у sigev_notify могут быть и другие значения.

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

>> Ok, верну сигналы :)

> у sigev_notify могут быть и другие значения.

Линукс других вроде бы не умеет. Кстати, SIGEV_THREAD эмулируется через сигналы глибцем: создаётся спецпоток, который ловит сигналы от таймера и создаёт новые потоки. Короче, производительность в заду... Можно юзать, если как раз и требуется потоки создавать по таймеру или делать ещё что-нибудь тяжёлое.

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

В ядре есть вот такие дефайны:
#define SIGEV_SIGNAL    0       /* notify via signal */
#define SIGEV_NONE      1       /* other notification: meaningless */
#define SIGEV_THREAD    2       /* deliver via thread creation */
#define SIGEV_THREAD_ID 4       /* deliver to thread */

Причем последнее - нестандартное расширение созданое как раз в помощь libc и не для пользователя особо не предназначено.

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

доставка signal notification - это _всегда_ сигнал. Он может отправляться в указанную нить, или в дефолтную (вот только не помню, как она выбирается в многонитвеом процессе). SIGEV_THREAD в Линуксе - это создание нити + SIGEV_THREAD_ID, насколько я понимаю.

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