【问题标题】:Infinite cycle in the parent process does not update the screen after using fork()父进程无限循环使用fork()后不更新屏幕
【发布时间】:2013-09-09 16:10:19
【问题描述】:

我需要编写使用 fork() 创建 2 个进程的 UNIX 应用程序,这两个进程都在屏幕上的不同位置打印当前时间。子进程结束后,父进程必须停止工作。我已经写了这段代码:

#include <ncurses.h>
#include <unistd.h>
#include <time.h>
#include <wait.h>
#include <sys/types.h>

struct Point2
{
    int X;
    int Y;
};

int kbhit()
{
    //getch() implementation
}

void printTime(const struct Point2 pt, const char* st)
{
    char buf[255];
    time_t rawtime;
    struct tm * timeinfo;

    time (&rawtime);
    timeinfo = localtime(&rawtime);
    sprintf(buf, "%s: %02d:%02d:%02d", st, timeinfo->tm_hour,
            timeinfo->tm_min, timeinfo->tm_sec);
    mvaddstr(pt.Y, pt.X, buf);
    refresh();
}

void childp(pid_t pid, const struct Point2 pt)
{
    while(kbhit() != 27)
    {
        printTime(pt, "CHLD");
        usleep(1000);
    }
}

void parentp(pid_t pid, const struct Point2 pt)
{
    struct Point2 newp = {pt.X, pt.Y + 1};
    while(1)
    {
        int stat;
        waitpid(pid, &stat, WNOHANG);
        if(WIFEXITED(stat) != 0)
            break;

        printTime(newp, "PARN");
            usleep(1000);
    }
}

int main(int argc, char* argv[])
{
    if(argc != 3)
    {
        printf("unable to load XY position for clock.\n");
        return 1;
    }

    initscr();
    refresh(); // <-- this refresh

    struct Point2 opt;
    opt.X = atoi(argv[1]);
    opt.Y = atoi(argv[2]);

    pid_t pid;
    pid = fork();

    switch(pid)
    {
        case -1:
            printw("Error");
            _exit(0);
        case 0:
            childp(pid, opt);
            break;
        default:
        parentp(pid, opt);
            break;

    }
    endwin();
    return 0;
}

程序一旦启动,输出一次“CHLD”和“PARN”时间,然后从子进程正确更新“CHLD”时间,但父进程的输出没有变化。此外,如果我在 main() "PARN" 时间字符串中评论 refresh() 调用,则根本不会出现。所以我的问题是:为什么父进程不更新屏幕?

更新。我已经删除了父函数循环中的几乎所有代码,现在它看起来像:

void parentp(pid_t pid, const struct Point2 pt)
{
    struct Point2 newp = {pt.X, pt.Y + 1};
    while(1)
    {
        printTime(newp, "PARN");
    }
}

但是还是不行

【问题讨论】:

  • waitpid(pid, &stat, WNOHANG);这会导致父进程一直等待,直到没有子进程,所以它打印一次的唯一原因是因为它在打印语句之前击败了您的子线程,然后当它循环时,子线程正在运行。
  • @Magn3s1um 很好,我必须做什么才能满足问题陈述?
  • 如果您希望他们俩随时都打印时间,则根本不要让父母等待。然后它将继续打印父母的时间。否则,每次您希望父母打印时间时,您只需从孩子向父母发送一个信号。
  • @Magn3s1um 声明之一是“正确关闭进程,不要杀死或终止它们”你能举个例子吗?
  • 如果你不能从父进程中杀死或终止它们,那么子进程将不得不正常返回。您不能在无限的 while 循环中执行此操作(除非在 while 循环中有 return 语句),因此除非您的子方法的 while 循环在一段时间后终止,否则您必须创建一个不始终为真(看起来孩子将在您的程序中正常终止)。

标签: c unix fork ncurses


【解决方案1】:

waitpid(pid, &amp;stat, WNOHANG); 工作正常。我不知道为什么,但问题出在mvaddstr(); 我把它改成了 printw() 瞧,它成功了!也许这是因为mvaddstr(); 没有更新整个屏幕。另一种方法是在调用 fork() 之前绘制 PARN 和 CHLD 时间,但我认为这既不是简单也不是优雅的解决方案。已使用printw().

【讨论】:

    猜你喜欢
    • 2014-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多