views:

115

answers:

2

Hello,

I am doing real time programming in C++, under Linux.

I have two process, let me say A and B. A process is being started periodically, every 5ms. B process is being started every 10ms. The process A is doing some change of data. The process B is reading that data and displays it.

I am confused about how to run periodically processes, and should I have two .cpp programs for each process?

+1  A: 

I think that, if possible, create a single process with two threads might be a good solution also, since it might be much easier for them to share resources and synchronize their data.

But, if you need more than this, then I think you need to be clearer when stating your problem.

Gianni
Problem is that I have to use processes and IPC... That is the task :(
MarijaS
@MarijaS Then, a single process with many threads is the simplest solution. You can just create global data structs and protect them with pthreads' mutexes.
Gianni
What if I really have to use process A and process B. Is the only way to create child process? Or I can create independent processes on some other way?Tnx!
MarijaS
+1  A: 

As a different solution, to create two separate processes that communicate with each other, all you really have to worry about is the IPC, not really how these processes are created; i.e. just create the two processes, A and B, as you would normally do (system() or fork() or popen() etc).

Now, the easiest way to make them talk to each other is using Named Pipes. They are one way, so you'll have to create one for A -> B and another for B -> A. They don't need any locking or synchronization since that is kinda done by the kernel/libc themselves. One you set up the pipes, you could use them as though they were simple network connections/sockets.

If you need 'MORE POWER(TM) (C)2010', then you'll have to use Shared Memory and Sempahores, or Message queues. They are, however, much more complicated, so I suggest you look into named pipes first.

Now, for the periodical running, the best way is to use usleep(T) in each program's main function; where the time T you use can be calculated from the last time you ran, instead of putting a fixed time in there, so that you guarantee that is a run took longer than expected, you'll sleep less time, to guarantee that every X milliseconds your program runs.

Another way of doing it, is using SIGALRM like this:

#include <iostream>
#include <string.h>
#include <errno.h>

#include <unistd.h>
#include <signal.h>

#include <pthread.h>
#include <semaphore.h>

static sem_t __semAlaram;

static void* waitForAlaram(void*)
{
    while( true )
    {
        sem_wait( &__semAlaram );
        std::cout << "Got alaram" << std::endl;
    }
    return NULL;
}


typedef void (*sighandler_t)(int);
static sighandler_t __handler = NULL;
static int count = 0;

static void sighandler(int signal)
{
    if ( signal == SIGALRM )
    {
        count++;
        sem_post( &__semAlaram );
        alarm(3);
    }
    else if ( __handler )
        __handler( signal );
}

int main(int argc, char **argv)
{
    if ( sem_init( &__semAlaram, 0, 0 ) != 0 )
    {
        std::cerr << strerror( errno ) << std::endl;
        return -1;
    }

    pthread_t thread;
    if ( pthread_create( &thread, NULL, waitForAlaram, NULL ) != 0 )
    {
        std::cerr << strerror( errno ) << std::endl;
        return -1;
    }

    __handler = signal( SIGALRM, sighandler );
    alarm(3);

    while( count < 5 )
    {
        sleep(1);
    }
    return 0;
}

You don't really need the thread in there, but it might be a good idea if you have more than 1 thing your program does, so that one task will not affect the timing of the critical one. Anyway, since I already had that example set up that way, it was easier to just copy-paste it the way it was. ;-)

Edit: Now that I read my post, I noticed a fatal flaw: the SIGALRM can only handle 1s precision, and you need ms precision. In that case, if you choose this solution, you'll have to use timer_create(); which is very similar to alarm(), but can handle ms precision. In linux, a man 2 timer_create will give you an example on how to use it.

Gianni
+1: for the "More Power" (I would capitalize it though ;) )
rubenvb
Thank you!I will try to deal with named pipes first.Any suggestions for periodical running?
MarijaS
@rubenv Sorry, my mistake. Fixed. :)
Gianni
@MarijaS OK, I've added that small bit...
Gianni
Thank you for your time! :)The problem is that the period of process A should be as much as it is possible accurate (5ms). For the process B it isn't so important. So, timer_create() would be ok? I have created independent processes, each in one .cpp file, and I am starting them from bash file. Is that OK? I don't have to make child processes in order to have parallel processes?
MarijaS
Yes, for 5ms `timer_create()` is the best option, however, with such low latencies you really need an RTOS and not any Linux, but that is a different issue. Starting the processes through bash or any other means is perfectly fine; you really don't seem to need anything special, except timing of course, that I can see.
Gianni