conartist6
conartist6

Reputation: 447

Simple Linux IPC Question

Currently I have a client process and a server process. The client process needs to contact the server process every so often to exchange data, but needs to know the server's pid to do so. How should the client know how to do this? I want to avoid repeated hard disk access. This application runs only under linux. Currently the server sets up a lock file with its pid which lives or a RAM disk. The client checks the file. How else can I accomplish this transaction efficiently such that the server can send a signal to the client? (note: client is PHP, server is c)

Upvotes: 2

Views: 1263

Answers (6)

Sujal Sheth
Sujal Sheth

Reputation: 392

I think you can use name IPC message queue in non_blocking mode. I don't know whether named pipe supportes non_blocking mode or not but if it is then you can also use that. In non_block mode, you just register queue descriptor to signal and go into general wait. Your process will get awake if there is any activity on queue. Please do some search over internet and you can find many example doing the same.

To give correct/exact answer, i should be knowing your design of server process.

Upvotes: 0

Doddy
Doddy

Reputation: 1259

I assume, when you say "process", these two are on the same machine? If so, you could use a named FIFO in the /tmp directory. This is an example of two processes using IPC with the named FIFO /tmp/test.fifo with 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;
}

So as long as both processes know the full path of the FIFO, they can read and write to it.

Upvotes: 4

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215457

Normally you don't use the pid but an address of some sort - an IP address (including port), a Unix domain socket address, a path in the filesystem, or some higher-level IPC system built on top of one of these (D-Bus, X, etc.) to reach and communicate with a server. The only thing the pid would be useful for is sending a signal, which is probably a really bad way to communicate, and won't work if you separate your client and server into separate privilege domains.

Upvotes: 2

MK.
MK.

Reputation: 34587

  • Unix Domain Sockets
  • D-Bus

Upvotes: 0

MarkR
MarkR

Reputation: 63586

Some ideas:

  1. do nothing; if you repeatedly read it, reading a disc file (on a proper, permanent disc) will not cause any IO, because the file will already be in cache.
  2. Refactor your system so you don't need to know the pid file
  3. Are you sure that you really care? Premature optimisation and all that. How many times per second are you doing this, 1000 or more?

Upvotes: 4

mipadi
mipadi

Reputation: 411022

Some other options include:

  1. Set up the server to listen on a specific port.
  2. The server could set up a named pipe, and the client could communicate with it over that.

Upvotes: 1

Related Questions