【问题标题】:How to implement two periodical processes in C++ under Linux?Linux下如何用C++实现两个周期进程?
【发布时间】:2010-07-23 16:10:38
【问题描述】:

我在 Linux 下使用 C++ 进行实时编程。

我有两个进程,让我说 A 和 B。一个进程定期启动,每 5 毫秒。 B进程每10ms启动一次。进程 A 正在对数据进行一些更改。进程 B 正在读取该数据并显示它。

我对如何定期运行进程感到困惑,我应该为每个进程设置两个 .cpp 程序吗?

【问题讨论】:

  • 当您询问作业时,请使用作业标签。那么答案就不太可能提出不符合您分配要求的替代方法(例如线程而不是多个进程)。
  • 好的。我会。我不知道。

标签: c++ linux process parallel-processing


【解决方案1】:

我认为,如果可能的话,创建具有两个线程的单个进程也可能是一个很好的解决方案,因为它们可能更容易共享资源和同步数据。

但是,如果你需要更多,那么我认为你在陈述问题时需要更清楚。

【讨论】:

  • 问题是我必须使用进程和IPC...这就是任务:(
  • @MarijaS 那么,具有多个线程的单个进程是最简单的解决方案。您可以创建全局数据结构并使用 pthread 的互斥锁来保护它们。
  • 如果我真的必须使用进程A和进程B怎么办。创建子进程的唯一方法是什么?或者我可以通过其他方式创建独立进程? Tnx!
【解决方案2】:

作为一种不同的解决方案,要创建两个相互通信的独立进程,您真正需要担心的是 IPC,而不是真正如何创建这些进程;即像通常那样创建两个进程 A 和 B(system()fork()popen() 等)。

现在,让他们互相交谈的最简单方法是使用NamedPipes。它们是一种方式,因此您必须为 A -> B 创建一个,为 B -> A 创建另一个。它们不需要任何锁定或同步,因为这有点由内核/libc 自己完成。一旦你设置了管道,你就可以像使用简单的网络连接/套接字一样使用它们。

如果您需要'MORE POWER(TM) (C)2010',则必须使用Shared MemorySempahores,或@987654325 @。但是,它们要复杂得多,因此我建议您先研究命名管道。

现在,对于定期运行,最好的方法是在每个程序的主函数中使用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 只能处理 1s 精度,而你需要 ms 精度。在这种情况下,如果您选择此解决方案,则必须使用timer_create()非常类似于alarm(),但可以处理毫秒精度。在 linux 中,man 2 timer_create 会给你一个如何使用它的例子。

【讨论】:

  • 谢谢!我将首先尝试处理命名管道。定期跑步有什么建议吗?
  • @rubenv 对不起,我的错误。固定的。 :)
  • 感谢您的宝贵时间! :) 问题是进程 A 的周期应该尽可能准确(5ms)。对于过程 B,它并不那么重要。那么, timer_create() 可以吗?我已经创建了独立的进程,每个进程都在一个 .cpp 文件中,并且我从 bash 文件开始。那样可以么?我不必为了拥有并行进程而创建子进程?
  • 是的,对于 5 毫秒,timer_create() 是最好的选择,但是,由于延迟如此之低,您确实需要 RTOS 而不是任何 Linux,但这是一个不同的问题。通过 bash 或任何其他方式启动进程非常好;你似乎真的不需要什么特别的东西,当然除了时间,我可以看到。
猜你喜欢
  • 2018-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-25
  • 2013-05-13
  • 1970-01-01
相关资源
最近更新 更多