Модераторы: xvr

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [pipe] возможность прервать блокирующую операцию 
:(
    Опции темы
cupper
Дата 18.3.2012, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



Цитата(svlary @ 18.3.2012,  05:28)
Цитата
pipe открывает из ОС.

   Это - как ?!

echo test > my.pipe
PM MAIL   Вверх
cupper
Дата 19.3.2012, 09:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



Цитата

Ну по сути как не крутись есть только два способа
* pselect + signal
* открыть pipe для того что бы завершить поток ожидающий его.

Второй явно безопаснее и проще.


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

И даже еще хуже, если наш тред работает, и весит на fopen. Наглядный эксперимент показал что мы спокойно в этот момент может удалить сам файл pipe физически. И тогда у нас и thread и поток вызывающий stop зависнут, и сделать уже ничего нельзя будет. 

Остается один только выход pselect + signal.

... О как долго до меня доходит все это... о как долго...
PM MAIL   Вверх
svlary
Дата 19.3.2012, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 8.9.2009

Репутация: 4
Всего: 4



Цитата(cupper @  18.3.2012,  15:25 Найти цитируемый пост)
echo test > my.pipe 

Если я правильно понял, то
  • Здесь изображена командная строка интерпретатора shell
  • Пользователь запускает некую программу по имени echo в usrer-space
  • Это может быть программа, которую написали лично Вы, а может быть из комплекта стандартных утилит
  • Стандартный вывод этой программы перенаправлен в некий файл my.pype. Возможно - это ранее созаднный Вами именованый FIFO.
Но я так и не понял, а причем тут ОПЕРАЦИОНКА, которая ОТКРЫВАЕТ именованый pipe ?
Или Вы имели в виду, что где-то в теле программы echo присутствует системный вызов open(..) ?
Но этот вызов есть во всех (!) прикладных программах. А ОПЕРАЦИОНКА (ядро Linux)  работает с файлами совсем по другому... 

Понимание того факта, что средство pipe, ПРЕДОСТАВЛЯЕМОЕ операционной системой (ядром Linux) предназначено именно
для взаимодействия двух прикладных программ (сервер и клиент) и дает ключ к пониманию того, как правильно использовать 
данную возможность ОС. 
  • Клиет и сервер всегда ВЗАИМОДЕЙСТВУЮТ.
  • Это взаимодействие всегда выполняется по некотрому протоколу.
  • Для открытия совместо используемого ресурса pipe используется протокол, описанный в соответствующих man ОС : man 7 pipe; man 3p pipe; man 2 pipe;
  • Отказ от использования стандартного протокола открытия pipe ведет к необходимости изобретения разного рода финтифлюшек

Добавлено через 13 минут и 49 секунд
Цитата(cupper @  19.3.2012,  09:05 Найти цитируемый пост)
 может удалить сам файл pipe физически. И тогда у нас и thread и поток вызывающий stop зависнут


Не понял... Вы хотите сказать, что операция open(...), обнаружив, что файла НЕТ,  вовсе не вернет -1 и не установит errno ==  ENOENT  а просто повиснет ?!
PM MAIL   Вверх
cupper
Дата 19.3.2012, 19:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



Цитата(svlary @ 19.3.2012,  12:16)
Цитата(cupper @  18.3.2012,  15:25 Найти цитируемый пост)
echo test > my.pipe 

Если я правильно понял, то



  • Здесь изображена командная строка интерпретатора shell


  • Пользователь запускает некую программу по имени echo в usrer-space


  • Это может быть программа, которую написали лично Вы, а может быть из комплекта стандартных утилит


  • Стандартный вывод этой программы перенаправлен в некий файл my.pype. Возможно - это ранее созаднный Вами именованый FIFO.


Но я так и не понял, а причем тут ОПЕРАЦИОНКА, которая ОТКРЫВАЕТ именованый pipe ?
Или Вы имели в виду, что где-то в теле программы echo присутствует системный вызов open(..) ?
Но этот вызов есть во всех (!) прикладных программах. А ОПЕРАЦИОНКА (ядро Linux)  работает с файлами совсем по другому... 

Понимание того факта, что средство pipe, ПРЕДОСТАВЛЯЕМОЕ операционной системой (ядром Linux) предназначено именно
для взаимодействия двух прикладных программ (сервер и клиент) и дает ключ к пониманию того, как правильно использовать 
данную возможность ОС. 



  • Клиет и сервер всегда ВЗАИМОДЕЙСТВУЮТ.


  • Это взаимодействие всегда выполняется по некотрому протоколу.


  • Для открытия совместо используемого ресурса pipe используется протокол, описанный в соответствующих man ОС : man 7 pipe; man 3p pipe; man 2 pipe;


  • Отказ от использования стандартного протокола открытия pipe ведет к необходимости изобретения разного рода финтифлюшек



Добавлено @ 12:29
Цитата(cupper @  19.3.2012,  09:05 Найти цитируемый пост)
 может удалить сам файл pipe физически. И тогда у нас и thread и поток вызывающий stop зависнут


простите но вы кэп smile

про всякое там правильное взаимодействие с pipe комментировать не буду.

Цитата(svlary @ 19.3.2012,  12:16)

Не понял... Вы хотите сказать, что операция open(...), обнаружив, что файла НЕТ,  вовсе не вернет -1 и не установит errno ==  ENOENT  а просто повиснет ?!

Уху smile Я проверял только для случая если open уже вызвали и заблокировались на ней. Если мы вызовем open просто на несуществующем файле, то тут поведение будет стандартное для этой функции.


Это сообщение отредактировал(а) cupper - 19.3.2012, 20:03
PM MAIL   Вверх
cupper
Дата 19.3.2012, 23:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



Вкуриваю тему сигналов. Споткнулся о
sigprocmask и pthread_sigmask. Ну вернее в начале я всттетил кучу примеров именно с sigprocmask. Далее смлучайным образов нашел pthread_sigmask, еще немного полистав интернет таки понял в чем разница. Но не нашел аналогичного для
sigaction... ну вот не хочу я обработчик ставить для всех, хочу только для текущего треда... что делать ?
PM MAIL   Вверх
svlary
Дата 20.3.2012, 07:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 207
Регистрация: 8.9.2009

Репутация: 4
Всего: 4



Цитата(cupper @  19.3.2012,  19:59 Найти цитируемый пост)
простите но вы кэп 

Может быть и так...  smile Но :
  • Мои очевидные программы работают (я написал с десяток систем клиент/сервер на pipe);
  • Ваши не очевидные - не рабатоают.

Не смею больше Вам мешать... smile
PM MAIL   Вверх
rsm
Дата 20.3.2012, 17:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 999
Регистрация: 16.3.2005

Репутация: 3
Всего: 62



Цитата(cupper @  20.3.2012,  01:26 Найти цитируемый пост)
не хочу я обработчик ставить для всех, хочу только для текущего треда

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

Цитата(cupper @  19.3.2012,  11:05 Найти цитируемый пост)
Открывая pipe со второй стороны что бы прервать первые мы рискуем заблокировать на этом

От этого помогает мультиплексирование (даже если оно как таковое не требуется), т.к. переданные дескрипторы проверяются на готовность к чтению. Если они не готовы, можно выйти либо по таймауту, либо по сигналу. Предлагаю всё-таки потыкать в приаттаченый выше пример.
PM MAIL   Вверх
cupper
Дата 21.3.2012, 10:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



Цитата(rsm @ 20.3.2012,  17:25)
Сигналы отправляются процессу, а не потоку.

Цитата

Name

pthread_kill - send a signal to a thread
Synopsis

#include <signal.h>int pthread_kill(pthread_t thread, int sig);
Compile and link with -pthread.
Description


 The pthread_kill() function sends the signal sig to thread, another thread in the same process as the caller. The signal is asynchronously directed to thread.
If sig is 0, then no signal is sent, but error checking is still performed; this can be used to check for the existence of a thread ID.


я как то не правильно понимаю либо вас либо описание выше ?

Цитата(rsm @ 20.3.2012,  17:25)

Предлагаю всё-таки потыкать в приаттаченый выше пример. 

Забыл :( Посмотрел. Удивлен. poll умеет реально определять были ли положены в pipe данные, когда select меня просто по бороде пускал и пролетал мимо. Тогда если скрестить pthread_kill и ppoll то вроде бы получиться то что надо.

Спасибо.


Это сообщение отредактировал(а) cupper - 21.3.2012, 10:24
PM MAIL   Вверх
rsm
Дата 21.3.2012, 16:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 999
Регистрация: 16.3.2005

Репутация: 3
Всего: 62



Цитата(cupper @  21.3.2012,  12:21 Найти цитируемый пост)
я как то не правильно понимаю либо вас либо описание выше?

Есть один нюанс в терминологии: в GNU/Linux потоки - это по факту процессы smile
PM MAIL   Вверх
cupper
Дата 21.3.2012, 23:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



Цитата(rsm @ 21.3.2012,  16:07)
Цитата(cupper @  21.3.2012,  12:21 Найти цитируемый пост)
я как то не правильно понимаю либо вас либо описание выше?

Есть один нюанс в терминологии: в GNU/Linux потоки - это по факту процессы smile

ну я так и знал что вы это скажите smile Так же по сути мы можем слать сигналы в тред (так как он по сути как процесс smile )

И еще, у меня вопрос по вашему примеру
Код

    /* устанавливаем процессу маску сигналов, блокируя приём всех сигналов */

    if (sigprocmask(SIG_SETMASK, signals_mask, NULL) == -1)
    {
        perror("sigprocmask()");
        return 2;
    }


Где опечатка ? В комментарии или в SIG_SETMASK ?

По сути этот код ничего не делает. И тут я подхожу к своему следующему вопросу. 
Я понимаю что делает sigaction и я понимаю что делает sigprocmask.

И так, первая функция регистрирует НАШ обработчик для заданного сигнала. 
Вторая функция напротив блокирует получение процессом сигнала.

Далее функции типа ppoll, pselect снимают блокировку сигналов которые вы укажите им в параметрах. Но, они гарантируют, что сразу после получения сего сигнала, его настройки будут возвращены в то состояние, которые было перед вызовом. В нашем случае состояние БЛОКИРОВАНИЯ сигнала.

Таким образом, нет смысла использовать их вместе. 
Но, стоит понять какую из них НУЖНО использовать. 

Итак, если мы используем sigprocmask то мы заблокируем сигнал, далее вызовем ppoll. Но как мы выйдя из ppoll сможем определить почему мы вышли ? из за сигнала или из за того что поступили данные ? Спецификаци ppoll говорит нам что errno будет установлено в EINTR если мы вышли из за сигнала. Гип гип ура.

Далее, если мы используем sigaction, то по выходу из ppoll мы собстно можем узнать это по какой то внешней переменной которую мы установили в обработчике сигнала. И опять таки гип гип ура smile

У вас в примере, реализовано сразу оба способа (что ни есть гуд) smile но по сути преобладает sigaction + ppoll как раз и за того с чего я начал сей  пост.

Если я где то ошибся поправьте меня. 

--
истина где то рядом

PM MAIL   Вверх
rsm
Дата 22.3.2012, 03:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 999
Регистрация: 16.3.2005

Репутация: 3
Всего: 62



Цитата(cupper @  22.3.2012,  01:08 Найти цитируемый пост)
по сути мы можем слать сигналы в тред (так как он по сути как процесс)

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

Цитата(cupper @  22.3.2012,  01:08 Найти цитируемый пост)
Если я где то ошибся поправьте меня

Я не понял, в чём состоит вопрос smile Подразумевалось, что приход сигнала можно выявить по коду EINTR и тогда можно не устанавливать свой обработчик сигналов? В таком случае вынужден огорчить - ppoll запросто может вернуть EINTR, даже если никакого сигнала не было.
PM MAIL   Вверх
cupper
Дата 22.3.2012, 09:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



Цитата(rsm @  22.3.2012,  03:20 Найти цитируемый пост)
Разные термины возникли не зря - не смотря на то, что потоки по факту процессы, сигналы в потоках и процессах обрабатываются по-разному. Не стоит об этом забывать, иначе однажды можно наступить на неприятные грабли 


пример граблей ? 

Цитата(rsm @  22.3.2012,  03:20 Найти цитируемый пост)
Я не понял, в чём состоит вопрос

первый на счет 
Код

   /* устанавливаем процессу маску сигналов, блокируя приём всех сигналов */
    if (sigprocmask(SIG_SETMASK, signals_mask, NULL) == -1)
    {
        perror("sigprocmask()");
        return 2;
    }

Сам вопрос в посте выше.

Цитата(rsm @  22.3.2012,  03:20 Найти цитируемый пост)
 В таком случае вынужден огорчить - ppoll запросто может вернуть EINTR, даже если никакого сигнала не было. 

пример ? Ну или хотя бы где это описано.


На счет sigprocmask и sigaction пока молчу, нужно еще поэксперементировать.
PM MAIL   Вверх
rsm
Дата 22.3.2012, 16:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 999
Регистрация: 16.3.2005

Репутация: 3
Всего: 62



Цитата(cupper @  22.3.2012,  11:04 Найти цитируемый пост)
пример граблей ?

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

Цитата(cupper @  22.3.2012,  11:04 Найти цитируемый пост)
первый на счет sigprocmask

Всё равно не понимаю, в чём вопрос? smile Смущает SIG_SETMASK? Это означает, что процессу следует установить новую маску сигналов, в точности равную заданной, игнорируя значение текущей маски.

Цитата(cupper @  22.3.2012,  11:04 Найти цитируемый пост)
пример ? Ну или хотя бы где это описано

У Стивенса этому посвящена целая глава 10.5, страница 373.
PM MAIL   Вверх
cupper
Дата 22.3.2012, 18:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



Цитата(rsm @  22.3.2012,  16:26 Найти цитируемый пост)
 однако диспозиция сигналов

чего ? можете пояснить ?


Цитата(rsm @  22.3.2012,  16:26 Найти цитируемый пост)
 Смущает SIG_SETMASK? Это означает, что процессу следует установить новую маску сигналов, в точности равную заданной, игнорируя значение текущей маски.

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

Цитата(rsm @  22.3.2012,  16:26 Найти цитируемый пост)
Цитата(cupper @  22.3.2012,  11:04 )
пример ? Ну или хотя бы где это описано

У Стивенса этому посвящена целая глава 10.5, страница 373. 

эх, будем вкуривать. Черт побери эти линуксы :(

Это сообщение отредактировал(а) cupper - 22.3.2012, 18:44
PM MAIL   Вверх
rsm
Дата 22.3.2012, 20:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 999
Регистрация: 16.3.2005

Репутация: 3
Всего: 62



Цитата(cupper @  22.3.2012,  20:33 Найти цитируемый пост)
чего ? можете пояснить ?

"Диспозиция" можно без потери смысла заменить на "callback" - не знаю, откуда переводчик книги Стивенса выкопал это необычайное слово (диспозиция) smile Для лучшего понимания рассмотрим применение простой, но устаревшей функции signal:

Код

/*
    установить диспозицию сигнала USR1 на игнорирование,
    т.е. сигнал USR1 будет игнорироваться процессом
*/
signal(SIGUSR1, SIG_IGN);

/*
    установить диспозицию сигнала USR1 на действие по-умолчанию,
    т.е. при получении процессом сигнала USR1 будет выполнено
    действие по-умолчанию (завершение процесса)
*/
signal(SIGUSR1, SIG_DEF);

/*
    созданный разработчиком callback для обработки сигналов
*/
static void on_signal(int signo)
{
    /* всякое */
}

/*
   установить диспозицию сигнала USR1 на callback `on_signal()',
   т.е. по приходу сигнала USR1 вызывать созданный разработчиком
   callback `on_signal()'
*/
signal(SIGUSR1, &on_signal);

Пример, полагаю, понятен? А теперь представим, что будет, если каждый вызов функции signal выполняется в отдельном потоке. Какая именно диспозиция будет назначена для сигнала USR1: игнорирование, действие по-умолчанию или callback? Если не синхронизировать потоки принудительно, получится игра в рулетку - нельзя предсказать, что будет диспозицией сигнала, т.к. достоверно неизвестно, какой поток выполнит вызов функции signal последним. Это и есть те грабли, про которые я упоминал выше, говоря об особенностях обработки сигналов в потоках.

P.S. В современных программах никогда не следует использовать функцию signal, ей на смену пришла функция sigaction.

Цитата(cupper @  22.3.2012,  20:33 Найти цитируемый пост)
я где то читал что сей параметр (или может просто похожий) заставляет сбросить state для заданных сигналов в дефолтное значение

У каждого процесса есть его текущая маска сигналов. Функция sigprocmask, принимая как аргумент новую маску сигналов, позволяет выполнить следующие действия:
а) SIG_BLOCK - добавить к текущей маске сигналы, заданные в новой маске;
б) SIG_SETMASK - установить текущую маску полностью идентичной новой маске;
в) SIG_UNBLOCK - убрать из текущей маски сигналы, заданные в новой маске;

Цитата(cupper @  22.3.2012,  20:33 Найти цитируемый пост)
Черт побери эти линуксы

К чему себя заставлять, есть же уютненькаяsmile
PM MAIL   Вверх
Страницы: (3) Все 1 [2] 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, xvr.

 
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Программирование под Unix/Linux | Следующая тема »


 




[ Время генерации скрипта: 0.0953 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.