Comments 22
Сейчас вспомнил, когда сдавал экзамен, мне задали вопрос: «Представим, что между двумя парами процессов инициализированы pipe и fifo соответственно. Какое может возникнуть отличие в их работе, если они взаимодействуют одинаково?»
На вопрос не ответил, а когда ушел, забыл спросить ответ. Может, кто-нибудь знает ответ на этот вопрос?
На вопрос не ответил, а когда ушел, забыл спросить ответ. Может, кто-нибудь знает ответ на этот вопрос?
У pipe нет имени и он создается для единичного использования. Пайп создается в рамках одного процесса и pipe могут использовать только наследники этого процесса. Самый простой пример — «cat some_file | grep some_name». Здесь пайп создается шеллом, в котором запущена команда.
В отличие от pipe, fifo создается именованным и выглядит как обычный файл в системе Linux, с некоторыми оговорками. Доступ к fifo могут иметь кто угодно, кто имеет соответствующие привилегии.
Вот пример fifo:
prwxr-x--x 1 serge users 0 Jun 18 13:43 my_named_pipe
В отличие от pipe, fifo создается именованным и выглядит как обычный файл в системе Linux, с некоторыми оговорками. Доступ к fifo могут иметь кто угодно, кто имеет соответствующие привилегии.
Вот пример fifo:
prwxr-x--x 1 serge users 0 Jun 18 13:43 my_named_pipe
Разница такая: время жизни pipe не превышает время жизни породившего его процесса.
fifo — его еще называют именованным каналом. FIFO нужно удалять при необходимости, т. к. цикл его существования не привязан к времени жизни процесса.
fifo — его еще называют именованным каналом. FIFO нужно удалять при необходимости, т. к. цикл его существования не привязан к времени жизни процесса.
UFO just landed and posted this here
В Linux shm_open() тупо открывает файл в /dev/shm, следовательно ls. Кстати чтобы избежать утечки ресурсов при работе с memmory mapped files, дескрипторы можно закрывать, а на файлы делать unlink как только сделали маппинг — на файлы есть счётчик ссылок. Заметил, что некоторые вообще дескриптор на замапленный файл передают через unix socket, чтобы unlink можно было сделать сразу же после open.
Эх, почему-то всегда интересные статьи по программированию появляются уже после экзамена =) все равно спасибо, продолжайте дальше!
А с чем связано, что имя семафора должно начинаться со слеша?
Сходу могу только сказать, что необходимость слеша в начале имени семафора продиктована требованиями POSIX стандарта. Почему это так, я сейчас не могу сказать. Обещаю поискать больше информации по этому поводу и ответить на ваш вопрос.
Вобщем вот что я накопал для вашего вопроса:
1. Стандарт POSIX утверждает что если имя нашего семафора начинается со слеша, то любой вызов sem_open с таким именем в любой процедуре должен возвращать дескриптор одного и того же семафора. Проще говора вызов sem_open("/semaphore",...) в любой процедуре вернет дескриптор одного и того же семафора. Тот же стандарт пишет, что если слеша в начале имени нет, то поведение стандартом не описывается, а ложится на плечи разработчиков sem_open. Проще говоря, что делать с именем семафора без слеша в начале «решает» конретная реализация sem_open.
2. Я не поленился глянуть в реализацию sem_open в стандартной библиотеке glibc. Так вот тамошняя реализация функции допускает отсутствие слеша. Более того, sem_open не пользуется слешом в начале имени, а смело его пропускает вот таким наглым образом:
sem_t * sem_open (const char *name, int oflag, ...) {
…
/* Construct the filename. */
while (name[0] == '/')
++name;
…
3. Ответ на ваш вопрос: имя семафора должно начинаться со слеша, скорее всего, потому, что семафор, как и разделенная память, должен создаваться в файловой системе ОС. Выглядеть это должно примерно так: /dev/sem/my_semaphore_name. Именно так реализовано в системе QNX, которая, к слову сказать, является полностью POSIX совместимой, в отличие от Linux.
1. Стандарт POSIX утверждает что если имя нашего семафора начинается со слеша, то любой вызов sem_open с таким именем в любой процедуре должен возвращать дескриптор одного и того же семафора. Проще говора вызов sem_open("/semaphore",...) в любой процедуре вернет дескриптор одного и того же семафора. Тот же стандарт пишет, что если слеша в начале имени нет, то поведение стандартом не описывается, а ложится на плечи разработчиков sem_open. Проще говоря, что делать с именем семафора без слеша в начале «решает» конретная реализация sem_open.
2. Я не поленился глянуть в реализацию sem_open в стандартной библиотеке glibc. Так вот тамошняя реализация функции допускает отсутствие слеша. Более того, sem_open не пользуется слешом в начале имени, а смело его пропускает вот таким наглым образом:
sem_t * sem_open (const char *name, int oflag, ...) {
…
/* Construct the filename. */
while (name[0] == '/')
++name;
…
3. Ответ на ваш вопрос: имя семафора должно начинаться со слеша, скорее всего, потому, что семафор, как и разделенная память, должен создаваться в файловой системе ОС. Выглядеть это должно примерно так: /dev/sem/my_semaphore_name. Именно так реализовано в системе QNX, которая, к слову сказать, является полностью POSIX совместимой, в отличие от Linux.
Тема про семафоры по-моему раскрыта не полно. А вообще, хорошо, спасибо.
Про d-bus почитаю с удовольствием.
Про d-bus почитаю с удовольствием.
Про DBus интересно было бы. Использовал его пару раз из Python и из консоли через qdbus, но не сильно вникал в подробности. В частности интересно — DBus где-то кроме десктопа актуален? Как у него с ограничением прав доступа?
А в статье хотелось бы еще видеть рекомендации что в каких случаях лучше применять…
А в статье хотелось бы еще видеть рекомендации что в каких случаях лучше применять…
а как связан описанный тут механизм shm с загрузкой so библиотек?
Хорошая статья, спасибо!
Давно хотел посмотреть про разделяемую память и тут на тебе. Спасибо.
Давно хотел посмотреть про разделяемую память и тут на тебе. Спасибо.
Хочу кое-что заметить/спросить. В случае разделяемой памяти — зачем использовать mmap/memcpy, если можно просто работать с дескриптором? Я вот тут экспериментировал и оказалось, что можно просто вызывать read/write для такого дескриптора и всё будет отлично работать. Так вроде даже проще…
Последовательно действий именно такая:
1) идентифицировать разделяемую область неким символичным именем, к примеру "/mySharedMem"
2) с помощью shm_open открыть файловый дескриптор на только что идентифицированной области
3) ftruncate'ом задать необходимый размер сегмента
4) с помощью mmap мапировать этот сегмент в свое адресное пространство
1) идентифицировать разделяемую область неким символичным именем, к примеру "/mySharedMem"
2) с помощью shm_open открыть файловый дескриптор на только что идентифицированной области
3) ftruncate'ом задать необходимый размер сегмента
4) с помощью mmap мапировать этот сегмент в свое адресное пространство
Подскажите пожалуйста как отличить именованный канал от обычного файла?
Реализовал работу с каналами точно так же как в примере с mkfifo.c
в итоге всё работает хорошо. Но если канал существует то он используется а не удаляется и создаётся заново. И тоже всё работает.
Но если вместо канала создан обычный файл то mkfifo не вернёт ошибку, а код чтения из этого файла будет выполнятся в бесконечном цикле без остановки.
Реализовал работу с каналами точно так же как в примере с mkfifo.c
Цитата кода из статьи
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#define NAMEDPIPE_NAME "/tmp/my_named_pipe"
#define BUFSIZE 50
int main (int argc, char ** argv) {
int fd, len;
char buf[BUFSIZE];
if ( mkfifo(NAMEDPIPE_NAME, 0777) ) {
perror("mkfifo");
return 1;
}
printf("%s is created\n", NAMEDPIPE_NAME);
if ( (fd = open(NAMEDPIPE_NAME, O_RDONLY)) <= 0 ) {
perror("open");
return 1;
}
printf("%s is opened\n", NAMEDPIPE_NAME);
do {
memset(buf, '\0', BUFSIZE);
if ( (len = read(fd, buf, BUFSIZE-1)) <= 0 ) {
perror("read");
close(fd);
remove(NAMEDPIPE_NAME);
return 0;
}
printf("Incomming message (%d): %s\n", len, buf);
} while ( 1 );
}
в итоге всё работает хорошо. Но если канал существует то он используется а не удаляется и создаётся заново. И тоже всё работает.
Но если вместо канала создан обычный файл то mkfifo не вернёт ошибку, а код чтения из этого файла будет выполнятся в бесконечном цикле без остановки.
Sign up to leave a comment.
Знакомство с межпроцессным взаимодействием на Linux