我需要编写使用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()中注释refresh()调用“PARN”时间字符串根本不显示。 所以我的问题是:为什么父进程不更新屏幕?
UPD。 我删除了父函数循环中的几乎所有代码,现在它看起来像:
void parentp(pid_t pid, const struct Point2 pt) { struct Point2 newp = {pt.X, pt.Y + 1}; while(1) { printTime(newp, "PARN"); } }但它仍然无法正常工作
I need to write UNIX appplication that creates 2 processes using fork(), both of these processes prints current time in different positions on the screen. Parent process must stop its work after the child process is over. I've written this code:
#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; }Once the program is started, it outputs once "CHLD" and "PARN" time, and then correctly updates "CHLD" time from the child proccess, but the output from the parent process does not change. Moreover, if I comment the refresh() call in main() "PARN" time string does not show up at all. So my question is: why the parent process does not updates the screen?
upd. I have deleted almost all code in parent function's cycle, now it looks like:
void parentp(pid_t pid, const struct Point2 pt) { struct Point2 newp = {pt.X, pt.Y + 1}; while(1) { printTime(newp, "PARN"); } }but it still not working
最满意答案
waitpid(pid, &stat, WNOHANG); 工作正常。 我不知道为什么,但问题出在mvaddstr(); 我将它更改为printw()并且瞧,它有效! 也许这种情况正在发生,因为mvaddstr(); 不会更新整个屏幕。 另一种方法是在调用fork()之前绘制PARN和CHLD时间,但我认为这既不简单也不优雅。 使用printw().
waitpid(pid, &stat, WNOHANG); worked correctly. I don't know why, but the problem was in mvaddstr(); I changed it to printw() and voila, it worked! Maybe that's happening because mvaddstr(); does not updates the whole screen. Another way is to draw PARN and CHLD time before calling fork(), but I think this is neither simple nor elegant solution. Used printw().
更多推荐
发布评论