Linux进程间通信
我必须实施一个测试程序(测验),除了显示问题和阅读答案外,还必须显示每一分钟过去的剩余时间.在完成检查时间后,通过完成问题或耗尽时间,程序必须从开始回来,在开始之前,我们输入候选人的姓名.必须使用进程完成此实现.下面是我到目前为止编写的代码.问题是我不确定我在进程和子进程之间进行了良好的沟通,特别是因为我没有使用管道.一些意见?
#include<stdio.h> #include<sys/types.h> #include<signal.h> #include<unistd.h> #include<sys/wait.h> #define T 180 void firstChildAction(){ static const char filename[] = "/home/osystems01/laura/text"; char question[100]; char answer[100]; FILE *file = fopen(filename,"r"); if(file != NULL){ while(fgets(question,sizeof question,file) != NULL){ fputs(question,stdout); scanf("%s",&answer); } fclose(file); } else{ perror(filename); } } void secondChildAction(){ int i; for(i = T; i >= 0; i-=60){ if( i/60 != 0){ printf("You have %d %s left.n",i/60,(i/60 > 1)?"minutes":"minute"); sleep(60); } else{ printf("The time is overn"); break; } } } int main() { pid_t pidA; pid_t pidB; pid_t wPid; char name[20]; while(1){ printf("Enter the candidate name or Quit to exit: n"); scanf("%s",&name); if(strcmp(name,"Quit") == 0 || strcmp(name,"quit") == 0){ printf("The program is terminating.....n"); break; } else{ pidA = fork(); if(pidA == 0){ firstChildAction(); exit(0); } else{ pidB = fork(); if(pidB == 0){ secondChildAction(); exit(0); } } int status; while(wPid = wait(&status)) > 0 ){ if(WIFEXITED(status)){ int result = WEXITSTATUS(status); printf("Exit status of %d is %dn",wPid,result); if(wPid == pidA){ kill(pidB,SIGTERM); kill(pidA,SIGTERM); } else if(wPid == pidB){ kill(pidA,SIGTERM); kill(pidB,SIGTERM); } } } } } return 0; } 解决方法
管道本身不要求您提供常规文件,但它们可以具有唯一的全局可见名称,该名称由您必须指定的(未使用的)文件名提供.文件的内容(如果有)由库处理.
(简单)管道用于相关进程(例如同一进程层次结构中的子进程和父进程)之间的通信,其中管道句柄可以很容易地传递给其他进程. 对于具有任何关系的进程,另一种风格称为“命名管道”,其中可以使用全局名称查找管道句柄(如我链接的问题的答案中所述).您可以将管道视为直接连接的说话管,允许两个进程使用读写功能对他们喜欢的任何内容进行闲聊.在Linux上,管道是一个单一的(一次是一个会话,一个是监听).在这种情况下,可以使用两个用于双向异步IO的管道(https://unix.stackexchange.com/questions/53641/how-to-make-bidirectional-pipe-between-two-programs).输入和输出的直接缓冲区是抽象的.就像网络套接字一样. 我建议在接受的答案中编译这个很好的例子:https://stackoverflow.com/a/2789967/1175253 编辑 带错误处理的示例代码.对待pipe.h& pipe.c作为库(链接NamedPipeReader和NamedPipeWriter). pipe.h #ifndef PIPE_H_ #define PIPE_H_ //C headers #include <errno.h> #include <assert.h> //Linux headers #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #ifdef __cplusplus extern "C" { #endif int open_named_pipe(const char* const name,const int permissions,const int mode,int* pipe_created); #ifdef __cplusplus } #endif #endif /* PIPE_H_ */ pipe.c #include "pipe.h" #include <stdio.h> int open_named_pipe(const char* const name,int* pipe_created) { int fd; assert(name); assert(permissions); assert(pipe_created); //Create or use an existing pipe special file if (0 == mkfifo(name,permissions)) { *pipe_created = 1; printf("Successfully created named pipe '%s'n",name); } else { switch (errno) { case EEXIST: //this is OK,as the other process might already has created the special file printf("Opened existing named pipe '%s'n",name); break; default: fprintf(stderr,"Failed to create or access named pipe '%s'n",name); perror(" "); return -1; }; } fd = open(name,mode); if (fd < 0) { perror("Could not open pipe for writing"); if (*pipe_created) { if (0 == unlink(name)) { *pipe_created = 0; } else { perror("Failed to unlink named pipe"); } } } return fd; } NamedPipeReader.c #include <stdlib.h> #include <stdio.h> #include <signal.h> #include "pipe.h" //Globals const char* const pipe_name = "/tmp/myfifo"; const int pipe_permissions = 0600; const size_t read_buffer_size = 1024; //[bytes] const size_t read_retry_delay = 25000; //[us] int fd = -1; int pipe_created = 0; char* read_buffer = NULL; //Handles EPIPE signal void signal_handler(int signal) { fprintf(stderr,"cought signal %dn",signal); } //Handles cleanup on exit void exit_handler(void) { if (read_buffer) free(read_buffer); if (fd >= 0) close(fd); //if this process created the FIFO,we unlink it if (pipe_created == 0) unlink(pipe_name); } int main() { //Locals int run = 1; int received = 0; //Install the exit handler atexit(&exit_handler); signal(EPIPE,signal_handler); signal(EACCES,signal_handler); //Allocate the buffer read_buffer = (char*) malloc(read_buffer_size); if (!read_buffer) { perror("Failed to allocate buffer"); return EXIT_FAILURE; } restart: ; //Close if already open if(fd >= 0) close(fd); //Create or use an existing pipe special file fd = open_named_pipe(pipe_name,pipe_permissions,O_RDONLY,&pipe_created); if (fd < 0) { return EXIT_FAILURE; } while (run) { assert(fd >= 0); assert(read_buffer_size > 1); received = read(fd,read_buffer,read_buffer_size - 1); if (received > 0) { //add a NUL char for string termination read_buffer[received] = '0'; printf("local process %llu received: %sn",(unsigned long long) getpid(),read_buffer); } else if (received == 0) { //EOF reached,this happens in case the writer has closed its handle. //Perform a delayed restart and recreate the named pipe usleep(read_retry_delay); printf("Restarting...n"); goto restart; } else { switch (errno) { case EAGAIN: //Wait,if the pipe is empty,//happens when opened with the O_NONBLOCK flag usleep(read_retry_delay); break; case EPIPE: case EBADF: case EBADFD: perror("Pipe error"); printf("Restarting...n"); goto restart; default: perror("Pipe error"); return EXIT_FAILURE; }; } } return EXIT_SUCCESS; } NamedPipeWriter.c #include <stdlib.h> #include <stdio.h> #include <signal.h> #include "pipe.h" //Globals const char* const pipe_name = "/tmp/myfifo"; const int pipe_permissions = 0600; const size_t write_buffer_size = 1024; //[bytes] const size_t write_retry_delay = 25000; //[us] const size_t write_interval = 1000000; int fd = -1; int pipe_created = 0; char* write_buffer = NULL; //Handles EPIPE signal void signal_handler(int signal) { fprintf(stderr,signal); } //Handles cleanup on exit void exit_handler(void) { if (write_buffer) free(write_buffer); if (fd >= 0) close(fd); //if this process created the FIFO,we unlink it if (pipe_created == 0) unlink(pipe_name); } //Main Function int main() { //Locals int run = 1; int sent = 0; int msg_len = 0; //Install the exit handler atexit(&exit_handler); signal(EPIPE,signal_handler); //Allocate the buffer write_buffer = (char*) malloc(write_buffer_size); if (!write_buffer) { perror("Failed to allocate buffer"); return EXIT_FAILURE; } restart: ; //Close if already open if(fd >= 0) close(fd); //Create or use an existing pipe special file fd = open_named_pipe(pipe_name,O_WRONLY,&pipe_created); if (fd < 0) { return EXIT_FAILURE; } while (run) { //Print message into the buffer msg_len = snprintf(write_buffer,write_buffer_size,"Greetings from process %llun",(unsigned long long) getpid()); { char* msg_ptr = write_buffer; char* msg_end = write_buffer + msg_len; while (msg_ptr != msg_end) { assert(fd >= 0); assert(msg_ptr < msg_end); sent = write(fd,msg_ptr,msg_end - msg_ptr); if (sent > 0) { msg_ptr += sent; } else if (sent == 0) { //retry delay for nonblocking writes usleep(write_retry_delay); } else { switch (errno) { case EAGAIN: //Wait,if the pipe is full,//happens when opened with the O_NONBLOCK flag usleep(write_retry_delay); break; case EPIPE: case EBADF: case EBADFD: perror("Pipe error"); printf("Restarting...n"); goto restart; default: perror("Pipe error"); return EXIT_FAILURE; }; } } printf("Written: %sn",write_buffer); usleep(write_interval); } } return EXIT_SUCCESS; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |