Простой Linux IPC Вопрос - PullRequest
       12

Простой Linux IPC Вопрос

2 голосов
/ 22 декабря 2010

В настоящее время у меня есть процесс клиента и процесс сервера. Клиентский процесс должен время от времени связываться с серверным процессом для обмена данными, но для этого ему нужно знать pid сервера. Как клиент должен знать, как это сделать? Я хочу избежать повторного доступа к жесткому диску. Это приложение работает только под Linux. В настоящее время сервер устанавливает файл блокировки со своим pid-файлом или RAM-диском. Клиент проверяет файл. Как еще можно эффективно выполнить эту транзакцию, чтобы сервер мог отправить сигнал клиенту? (примечание: клиент - PHP, сервер - c)

Ответы [ 6 ]

3 голосов
/ 22 декабря 2010

Я полагаю, когда вы говорите "процесс", эти два находятся на одной машине?Если это так, вы можете использовать именованный FIFO в каталоге /tmp.Это пример двух процессов, использующих IPC с именем FIFO /tmp/test.fifo с fork():

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/stat.h>

int errno;

int main(int argc, char** argv)
{
    char fifo_path[] = "/tmp/test.fifo";
    char buffer[128];

    int result = mkfifo(fifo_path, 0600);

    printf("mkfifo result = %d\n", result);

    if (errno == EEXIST)
        printf("errno == EEXIST\n");

    pid_t child = fork();

    if (child == 0)
    {
        printf("%d> child; opening fifo \"%s\" for writing\n", getpid(),
                 fifo_path);

        FILE* fifo = fopen(fifo_path, "w");
        char in_buffer[128];

        fgets(in_buffer, 128, stdin);

        fputs(in_buffer, fifo);

        fclose(fifo);
    }
    else
    {
        printf("%d> parent; opening fifo \"%s\" for reading\n", getpid(),
                 fifo_path);

        FILE* fifo = fopen(fifo_path, "r");

        fgets(buffer, 128, fifo);

        if (buffer[0] == EOF)
            printf("%d> got EOF\n", getpid());
        else
        {
            buffer[strlen(buffer) - 1] = 0;
            printf("%d> read string \"%s\"\n", getpid(), buffer);
        }

        fclose(fifo);
    }

    return 0;
}

Так что, пока оба процесса знают полный путь FIFO, они могут читать и записывать вэто.

3 голосов
/ 22 декабря 2010

Некоторые идеи:

  1. ничего не делать; если вы неоднократно читаете его, чтение файла диска (на правильном постоянном диске) не вызовет ввода-вывода, поскольку файл уже будет в кеше.
  2. Рефакторинг вашей системы, так что вам не нужно знать файл pid
  3. Вы уверены, что действительно заботитесь? Преждевременная оптимизация и все такое. Сколько раз в секунду вы делаете это, 1000 или больше?
2 голосов
/ 22 декабря 2010

Обычно вы используете не pid, а какой-то адрес - IP-адрес (включая порт), адрес сокета домена Unix, путь в файловой системе или какую-либо высокоуровневую систему IPC, построенную поверх одного из них. из них (D-Bus, X и т. д.) для достижения и связи с сервером. Единственная вещь, для которой pid был бы полезен, это отправка сигнала, который, вероятно, является действительно плохим способом связи, и не будет работать, если вы разделите ваш клиент и сервер на отдельные домены привилегий.

1 голос
/ 22 декабря 2010

Некоторые другие параметры включают в себя:

  1. Настройка сервера на прослушивание определенного порта.
  2. Сервер может настроить именованный канал, и клиент может связаться с нимза это.
0 голосов
/ 23 апреля 2013

Я думаю, вы можете использовать имя очереди сообщений IPC в режиме non_blocking. Я не знаю, поддерживает ли named pipe режим non_blocking или нет, но если это так, то вы также можете использовать это. В режиме non_block вы просто регистрируете дескриптор очереди для подачи сигнала и переходите в общее ожидание. Ваш процесс проснется, если в очереди будет какое-либо действие. Пожалуйста, сделайте поиск по Интернету, и вы можете найти много примеров, делающих то же самое.

Чтобы дать правильный / точный ответ, я должен знать ваш дизайн серверного процесса.

0 голосов
/ 22 декабря 2010
  • доменные сокеты Unix
  • D-Bus
...