Как реализовать два периодических процесса в C ++ под Linux? - PullRequest
2 голосов
/ 23 июля 2010

Я занимаюсь программированием в реальном времени на C ++, под Linux.

У меня есть два процесса, позвольте мне сказать A и B. Процесс запускается периодически, каждые 5 мс. Процесс B запускается каждые 10 мс. Процесс А выполняет некоторое изменение данных. Процесс B читает эти данные и отображает их.

Я не совсем понимаю, как периодически запускать процессы, и мне нужно иметь две программы .cpp для каждого процесса?

Ответы [ 2 ]

1 голос
/ 26 июля 2010

В качестве другого решения для создания двух отдельных процессов, которые взаимодействуют друг с другом, все, о чем вам действительно нужно беспокоиться, это IPC, а не как эти процессы создаются;т.е. просто создайте два процесса, A и B, как вы это обычно делаете (system() или fork() или popen() и т. д.).

Теперь самый простой способ заставить их общаться друг с другом -используя Named Pipes .Это один из способов, поэтому вам придется создать один для A -> B, а другой для B -> A. Им не нужна блокировка или синхронизация, так как это делается самим ядром / libc.Когда вы настроили каналы, вы могли бы использовать их, как если бы они были простыми сетевыми соединениями / сокетами.

Если вам нужно ' БОЛЬШЕ МОЩНОСТИ (TM) (C) 2010 ', тогда вам придется использовать Shared Memory и Sempahores или Очереди сообщений .Однако они намного сложнее, поэтому я предлагаю вам сначала изучить именованные каналы.

Теперь для периодического запуска лучший способ - использовать usleep(T) в основной функции каждой программы;где время T, которое вы используете, может быть рассчитано по времени последнего запуска, вместо того, чтобы указывать фиксированное время, чтобы вы гарантировали, что пробег занял больше времени, чем ожидалось, вы будете спать меньше времени, чтобы гарантировать, что каждый Xмиллисекунды запускается ваша программа.

Другой способ сделать это - использовать SIGALRM следующим образом:

#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;
}

Вам не нужен поток, но это может быть хорошей идеейесли у вас есть более чем одна вещь, которую делает ваша программа, так что одна задача не повлияет на время критической.В любом случае, так как у меня уже был такой пример, проще было просто скопировать и вставить его, как было.; -)

Редактировать: Теперь, когда я прочитал свой пост, я заметил фатальный недостаток: SIGALRM может обрабатывать только с точностью до 1 с, и вам нужна мс точность.В этом случае, если вы выберете это решение, вам придется использовать timer_create();который очень похож на alarm(), но может обрабатывать мс с точностью.В Linux man 2 timer_create даст вам пример того, как его использовать.

1 голос
/ 23 июля 2010

Я думаю, что, если это возможно, создание отдельного процесса с двумя потоками также может быть хорошим решением, так как им будет гораздо проще обмениваться ресурсами и синхронизировать свои данные.нужно больше, чем это, тогда я думаю, что вам нужно быть более ясным при изложении вашей проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...