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.