多进程如何使用相同的ncurses屏幕?

时间:2016-11-05 06:57:47

标签: c++ multiprocessing ncurses

我正在用ncurses编写一个c ++多进程程序。

每个过程都需要在屏幕上显示内容。

我的示例代码:

unsigned int

但它只能在屏幕上显示一个进程的信息。

我该如何解决?

2 个答案:

答案 0 :(得分:1)

该示例创建了两个4x4窗口,第二个偏移为8,8。所以他们没有共同的

由于你正在使用 fork (而不是 vfork ),这两个进程应该有单独的地址空间,并且一个进程应该没有办法刷新在其他进程中已修改的窗口。在某些情况下,开发人员选择将vforkfork等同起来。使用Linux,vfork manual page comments

  

标准说明
  (来自POSIX.1) vfork() 功能与 fork(2) 具有相同的效果,   除非行为 未定义 ,否则由 vfork() 创建的流程   修改除 pid_t 类型的变量以外的任何数据   存储来自 vfork() 的返回值,或从函数中返回   在成功调用 vfork() 或其中一个 _exit(2) exec(3) ,或调用任何其他函数强>功能家族。

但接着说

  

标准对 vfork() 的要求   那些放在 fork(2) 上的,所以这两者都是实现的   同义词 合规 。特别是程序员不能依赖   在父母被阻止之前,直到孩子终止或   调用 execve(2) ,并且不能依赖任何特定行为   尊重共享记忆。

兼容是一个开发人员,他认为让这两个函数相似并不重要......

fork manual page断言有单独的地址空间:

  

子进程和父进程在 单独的内存中运行   空间 即可。在 fork() 时,两个内存空间都相同   内容。内存写入,文件映射( mmap(2) )和取消映射   其中一个进程执行的( munmap(2) )不会影响   其他

但我们在vfork的描述中留下了这种模糊性。作为此vfork行为的一部分,您的程序可能无法更新属于父进程的窗口 - 并且在建议的答案中刷新两个窗口仅确认fork函数是伪装vfork

POSIX目前没有vfork的页面。它有one herefork描述值得一读。)

无论哪种方式,使用vfork实际上都不会改进。如果你必须在相同的地址空间内工作,那就是线程的用途。如果你必须使用单独的进程,让一个进程更新屏幕,其他进程与管道进行通信就是人们实际做的事情。

评论说,fork已过时。 POSIX在这方面有不同的说法。引用posix_spawn

的基本原理
  

引入了posix_spawn()函数及其关系posix_spawnp()以克服fork()的以下感知困难:fork()函数在没有交换或动态地址转换的情况下很难或无法实现。

     
      
  • 对于实时环境,交换通常太慢。

  •   
  • 在POSIX可能有用的任何地方都无法使用动态地址转换。

  •   
  • 只要必须在没有地址转换或其他MMU服务的情况下运行,进程就无法简单地选择POSIX。

  •   
     

因此,POSIX需要流程创建和文件执行原语,无需地址转换或其他MMU服务即可高效实现。

     

posix_spawn()函数可以作为库例程实现,但是posix_spawn()和posix_spawnp()都被设计为内核操作。此外,尽管它们可能是许多fork()/ exec对的有效替代品,但它们的目标是为fork(), 不提供插入式替换的系统提供有用的进程创建原语。 for fork()/ exec。

进一步阅读:

答案 1 :(得分:0)

我已经破解了一些丑陋的东西,大致有效但却显示出问题所在。我怀疑其他进程与之通信的单个窗口管理器进程会更好 - 或者是一些可怕的互斥体。

#include <stdlib.h>
#include <unistd.h>
#include <curses.h>
int main() {
  initscr();
  noecho();
  curs_set(0);
    WINDOW *win0 = newwin(4, 4, 0, 0);
    WINDOW *win1 = newwin(4, 4, 8, 8);

  int flag = fork();
  if (flag == -1)
    exit(1);
  else if (flag == 0) {
    int n = 0;
    while (1) {
      mvwprintw(win0, 0, 0, "%d", n % 9);
      wrefresh(win0);
      wrefresh(win1);
      n = (n + 1) % 9;
      sleep(1);
    }
  }
  else {
    int n = 0;
    while (1) {
      mvwprintw(win1, 0, 0, "%d", n % 9);
      wrefresh(win1);
      wrefresh(win0);
      n = (n + 1) % 9;
      sleep(1);
    }
  }
  endwin();

  return 0;
}

enter image description here