1

I need the simplest most reliable IPC method from one C++ app running on the RPi to another app.

All I'm trying to do is send a string message of 40 characters from one app to another

The first app is running as a service on boot, the other app is started at a later time and is frequently exited and restarted for debugging

The frequent debugging for the second app is whats causing problems with the IPCs I've tried so far

I've tried about 3 different methods and here is where they failed:

  1. File FIFO, the problem is one program hangs while the other program is writing to the file

  2. Shared memory: cannot initialize on one thread and read from another thread. Also frequent exiting while debugging causing GDB crashes with the following GDB command is taking too long to complete -stack-list-frames --thread 1

  3. UDP socket with localhost - same issue as above, plus improper exits block the socket, forcing me to reboot device

  4. Non blocking pipe - not getting any messages on the receiving process

What else can I try? I dont want to get the DBus library, seems too complex for this application.

Any simple server and client code or a link to it would be helpful

Here is my non-blockign pipe code, that doesnt work for me, I assume its because I dont have a reference to the pipe from one app to the other

Code sourced from here: https://www.geeksforgeeks.org/non-blocking-io-with-pipes-in-c/

char* msg1 = "hello"; 
char* msg2 = "bye !!"; 
int p[2], i;

bool InitClient()
{   
    // error checking for pipe 
    if(pipe(p) < 0) 
        exit(1); 

    // error checking for fcntl 
    if(fcntl(p[0], F_SETFL, O_NONBLOCK) < 0) 
        exit(2); 

    //Read
    int nread; 
    char buf[MSGSIZE]; 

    // write link 
    close(p[1]); 

    while (1) { 

        // read call if return -1 then pipe is 
        // empty because of fcntl 
        nread = read(p[0], buf, MSGSIZE); 
        switch (nread) { 
        case -1: 

            // case -1 means pipe is empty and errono 
            // set EAGAIN 
            if(errno == EAGAIN) { 
                printf("(pipe empty)\n"); 
                sleep(1); 
                break; 
            } 

        default: 

            // text read 
            // by default return no. of bytes 
            // which read call read at that time 
            printf("MSG = % s\n", buf); 
        } 
    } 

    return true;
}   

bool InitServer()
{      
    // error checking for pipe 
    if(pipe(p) < 0) 
        exit(1); 

    // error checking for fcntl 
    if(fcntl(p[0], F_SETFL, O_NONBLOCK) < 0) 
        exit(2); 


    //Write
    // read link 
    close(p[0]); 

    // write 3 times "hello" in 3 second interval 
    for(i = 0 ; i < 3000000000 ; i++) { 
        write(p[0], msg1, MSGSIZE); 
        sleep(3); 
    } 

    // write "bye" one times 
    write(p[0], msg2, MSGSIZE); 

    return true;
}       
Mi Po
  • 1,123
  • 2
  • 12
  • 21
  • 1
    What problems did you have exactly with shared memory -- what did you try? Have a look to `boost.interprocess` https://theboostcpplibraries.com/boost.interprocess-managed-shared-memory – florgeng Jan 10 '20 at 23:15
  • 4
    FIFO or Unix domain socket with non-blocking io. – Shawn Jan 10 '20 at 23:17
  • 1
    non-blocking pipe is one of the better ways to go. add the code you used for this and someone can probably let you know what went wrong. – user4581301 Jan 10 '20 at 23:29
  • 1
    The geeks for geeks pipe code would spam the console with "(pipe empty)" messages making it hard to see if you really did get a message. Obviously this is a bad idea for your actual case, but for testing, consider adding a half second sleep to the client loop. In your actual program you would poll the pipe to see if data had arrived periodically between other tasks. – user4581301 Jan 11 '20 at 00:15
  • 1
    Redis is dead simple and you can inject into it or read from it using C/C++, Python, PHP, or bash commandline so it's simple to debug... https://stackoverflow.com/a/58521903/2836621 – Mark Setchell Jan 11 '20 at 23:24

1 Answers1

0

Please consider ZeroMQ

https://zeromq.org/

It is lightweight and has wrapper for all major programming languages.

Amit Vujic
  • 1,632
  • 1
  • 24
  • 32