user-0 提问: 高手们帮我看下这段小程序

回复:
user: user-0
content: 谢谢论坛里各位兄弟的热心解答

user: user-1
content: 可以试试在父进程中捕获ctrl+c对应的signal，捕获到时，向子进程发送signal让其结束，再自己结束。

user: user-2
content: 引用 17 楼 wanren13 的回复:[quote=引用 14 楼 shangyu0801 的回复:] [quote=引用 8 楼 wanren13 的回复:] [quote=引用 5 楼 shangyu0801 的回复:] [quote=引用 2 楼 wanren13 的回复:] [quote=引用 1 楼 worldy 的回复:] 进程间读写没有同步？ 请赐教： 如何同步？ 另外就代码本身而言，该如何修改？[/quote] 不是互斥的原因吧，这里貌似没有临界资源啊。 我跑了遍你的代码，运行输入时有时会出现死循环。是因为主进程中的free()释放出了问题导致主进程先退了，子进程读管道操作不在阻塞了，就不断的读啊读。造成死循环的现象。 主进程的代码申请空间后，没有清零吧。应该是溢出导致段错误。 楼主仔细看下这些代码是有问题的: char *numbers = (char*) malloc(len);             // concatenate two strings       strcpy(numbers, num1);       numbers[strlen(num1)]=' ';       //+ -> numbers[strlen(num1)+1]='\0';       strcat(numbers, num2);        [/quote]  应该不用加'\0' 这是strcat的解释：  char * strcat ( char * destination, const char * source ); Concatenate strings Appends a copy of the source string to the destination string. The terminating null character in destination is overwritten by the first character of source, and a null-character is included at the end of the new string formed by the concatenation of both in destination.  第二个string会把第一个string的null terminator覆盖掉。我在string中加入空格是为了把两个数字分开。。。  个人觉得应该是子进程在判断while循环的时候出了问题，read函数读到到字母，循环就会退出，等到下个循环开始，read又开始从之前的字母开始读。这是我的推测，但是我不清楚该如何解决这个问题。（如何清空read还没有读的剩下的内容，然后继续等待父进程的管道输入？）[/quote] 你试了增加那一句的代码么？ 如果你想增加空格，用strcat(numbers," ");不要覆盖结尾的’\0'。[/quote]  谢谢高手指点，好像运行暂时没有问题了。再多问个衍生的问题，如果我按ctrl+c结束了父进程，那么子进程会怎么样？变成孤儿进程，无止境的运行下去？[/quote] 是的，只是在进程中查找并kill掉。

user: user-0
content: 引用 19 楼 ak47_wz 的回复:初看感觉是这里出错了。  while(read(fd[0], &c, 1) && skip != 1)  skip = 1之后直接跳出，但是还有数据在管道中，没有读干净，也没有清除。下次在运行的时候，这些垃圾数据应该仍然存在。  先去接人吃饭哈，回来在调看看。 等大侠回来赐教，什么函数可以清除？

user: user-3
content: 初看感觉是这里出错了。  while(read(fd[0], &c, 1) && skip != 1)  skip = 1之后直接跳出，但是还有数据在管道中，没有读干净，也没有清除。下次在运行的时候，这些垃圾数据应该仍然存在。  先去接人吃饭哈，回来在调看看。

user: user-1
content: _pipe Creates a pipe for reading and writing.  int _pipe( int *phandles, unsigned int psize, int textmode );  Routine Required Header Optional Headers Compatibility  _pipe <io.h> <fcntl.h>,1 <errno.h>2 Win 95, Win NT    1 For _O_BINARY and _O_TEXT definitions.  2 errno definitions.  For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  _pipe returns 0 if successful. It returns –1 to indicate an error, in which case errno is set to one of two values: EMFILE, which indicates no more file handles available, or ENFILE, which indicates a system file table overflow.  Parameters  phandles[2]  Array to hold read and write handles  psize  Amount of memory to reserve  textmode  File mode  Remarks  The _pipe function creates a pipe. A pipe is an artificial I/O channel that a program uses to pass information to other programs. A pipe is similar to a file in that it has a file pointer, a file descriptor, or both, and can be read from or written to using the standard library’s input and output functions. However, a pipe does not represent a specific file or device. Instead, it represents temporary storage in memory that is independent of the program’s own memory and is controlled entirely by the operating system.  _pipe is similar to _open but opens the pipe for reading and writing, returning two file handles instead of one. The program can use both sides of the pipe or close the one it does not need. For example, the command processor in Windows NT creates a pipe when executing a command such as  PROGRAM1 | PROGRAM2  The standard output handle of PROGRAM1 is attached to the pipe’s write handle. The standard input handle of PROGRAM2 is attached to the pipe’s read handle. This eliminates the need for creating temporary files to pass information to other programs.  The _pipe function returns two handles to the pipe in the phandles argument. The element phandles[0] contains the read handle, and the element phandles[1] contains the write handle. Pipe file handles are used in the same way as other file handles. (The low-level input and output functions _read and _write can read from and write to a pipe.) To detect the end-of-pipe condition, check for a _read request that returns 0 as the number of bytes read.  The psize argument specifies the amount of memory, in bytes, to reserve for the pipe. The textmode argument specifies the translation mode for the pipe. The manifest constant _O_TEXT specifies a text translation, and the constant _O_BINARY specifies binary translation. (See fopen for a description of text and binary modes.) If the textmode argument is 0, _pipe uses the default translation mode specified by the default-mode variable _fmode.  In multithreaded programs, no locking is performed. The handles returned are newly opened and should not be referenced by any thread until after the _pipe call is complete.  In order to use the _pipe function to communicate between a parent and a child process, each process must have only one handle open on the pipe. The handles must be opposites: if the parent has a read handle open, then the child must have a write handle open. The easiest way to do this is to OR (|) the _O_NOINHERIT flag with textmode. Then, use _dup or _dup2 to create an inheritable copy of the pipe handle you wish to pass to the child. Close the original handle, and spawn the child process. Upon returning from the spawn call, close the 'duplicate' handle in the parent process. See Example 2 below for more information.  In Windows NT and Windows 95, a pipe is destroyed when all of its handles have been closed. (If all read handles on the pipe have been closed, writing to the pipe causes an error.) All read and write operations on the pipe wait until there is enough data or enough buffer space to complete the I/O request.  Example 1  /* PIPE.C: This program uses the _pipe function to pass streams of  * text to spawned processes.  */  #include <stdlib.h> #include <stdio.h> #include <io.h> #include <fcntl.h> #include <process.h> #include <math.h>  enum PIPES { READ, WRITE }; /* Constants 0 and 1 for READ and WRITE */ #define NUMPROBLEM 8  void main( int argc, char *argv[] ) {     int hpipe[2];    char hstr[20];    int pid, problem, c;    int termstat;     /* If no arguments, this is the spawning process */    if( argc == 1 )    {        setvbuf( stdout, NULL, _IONBF, 0 );        /* Open a set of pipes */       if( _pipe( hpipe, 256, O_BINARY ) == -1 )           exit( 1 );         /* Convert pipe read handle to string and pass as argument         * to spawned program. Program spawns itself (argv[0]).        */       itoa( hpipe[READ], hstr, 10 );       if( ( pid = spawnl( P_NOWAIT, argv[0], argv[0],              hstr, NULL ) ) == -1 )           printf( "Spawn failed" );        /* Put problem in write pipe. Since spawned program is         * running simultaneously, first solutions may be done         * before last problem is given.        */       for( problem = 1000; problem <= NUMPROBLEM * 1000; problem += 1000)       {           printf( "Son, what is the square root of %d?\n", problem );          write( hpipe[WRITE], (char *)&problem, sizeof( int ) );        }        /* Wait until spawned program is done processing. */       _cwait( &termstat, pid, WAIT_CHILD );       if( termstat & 0x0 )          printf( "Child failed\n" );         close( hpipe[READ] );       close( hpipe[WRITE] );     }     /* If there is an argument, this must be the spawned process. */    else    {        /* Convert passed string handle to integer handle. */       hpipe[READ] = atoi( argv[1] );        /* Read problem from pipe and calculate solution. */       for( c = 0; c < NUMPROBLEM; c++ )       {          read( hpipe[READ], (char *)&problem, sizeof( int ) );         printf( "Dad, the square root of %d is %3.2f.\n",                  problem, sqrt( ( double )problem ) );        }    } }   Output  Son, what is the square root of 1000? Son, what is the square root of 2000? Son, what is the square root of 3000? Son, what is the square root of 4000? Son, what is the square root of 5000? Son, what is the square root of 6000? Son, what is the square root of 7000? Son, what is the square root of 8000? Dad, the square root of 1000 is 31.62. Dad, the square root of 2000 is 44.72. Dad, the square root of 3000 is 54.77. Dad, the square root of 4000 is 63.25. Dad, the square root of 5000 is 70.71. Dad, the square root of 6000 is 77.46. Dad, the square root of 7000 is 83.67. Dad, the square root of 8000 is 89.44.   Example 2  // This is a simple filter application.  It will spawn  // the application on  command line. But before spawning  // the application, it will create a pipe that will direct the  // spawned application's stdout to the filter.  The filter  // will remove ASCII 7 (beep) characters.  // Beeper.Cpp  /* Compile options needed: None */ #include <stdio.h> #include <string.h>  int main() {    int   i;    for(i=0;i<100;++i)       {          printf("\nThis is speaker beep number %d... \n\7", i+1);       }    return 0; }   // BeepFilter.Cpp /* Compile options needed: none    Execute as: BeepFilter.exe <path>Beeper.exe */ #include <windows.h> #include <process.h> #include <memory.h> #include <string.h> #include <stdio.h> #include <fcntl.h> #include <io.h>  #define   OUT_BUFF_SIZE 512 #define   READ_HANDLE 0 #define   WRITE_HANDLE 1 #define   BEEP_CHAR 7  char szBuffer[OUT_BUFF_SIZE];  int Filter(char* szBuff, ULONG nSize, int nChar) {    char* szPos = szBuff + nSize -1;    char* szEnd = szPos;    int nRet = nSize;     while (szPos > szBuff)    {       if (*szPos == nChar)          {             memmove(szPos, szPos+1, szEnd - szPos);             --nRet;          }       --szPos;    }    return nRet; }  int main(int argc, char** argv) {    int nExitCode = STILL_ACTIVE;    if (argc >= 2)    {       HANDLE hProcess;       int hStdOut;       int hStdOutPipe[2];        // Create the pipe       if(_pipe(hStdOutPipe, 512, O_BINARY | O_NOINHERIT) == -1)          return   1;        // Duplicate stdout handle (next line will close original)       hStdOut = _dup(_fileno(stdout));        // Duplicate write end of pipe to stdout handle       if(_dup2(hStdOutPipe[WRITE_HANDLE], _fileno(stdout)) != 0)          return   2;        // Close original write end of pipe       close(hStdOutPipe[WRITE_HANDLE]);        // Spawn process       hProcess = (HANDLE)spawnvp(P_NOWAIT, argv[1],         (const char* const*)&argv[1]);        // Duplicate copy of original stdout back into stdout       if(_dup2(hStdOut, _fileno(stdout)) != 0)          return   3;        // Close duplicate copy of original stdout       close(hStdOut);        if(hProcess)       {          int nOutRead;          while   (nExitCode == STILL_ACTIVE)          {             nOutRead = read(hStdOutPipe[READ_HANDLE],               szBuffer, OUT_BUFF_SIZE);             if(nOutRead)             {                nOutRead = Filter(szBuffer, nOutRead, BEEP_CHAR);                fwrite(szBuffer, 1, nOutRead, stdout);             }              if(!GetExitCodeProcess(hProcess,(unsigned long*)&nExitCode))                return 4;          }       }    }     printf("\nPress \'ENTER\' key to continue... ");    getchar();    return nExitCode; }   Process and Environment Control Routines  See Also   _open

user: user-0
content: 引用 14 楼 shangyu0801 的回复:[quote=引用 8 楼 wanren13 的回复:] [quote=引用 5 楼 shangyu0801 的回复:] [quote=引用 2 楼 wanren13 的回复:] [quote=引用 1 楼 worldy 的回复:] 进程间读写没有同步？ 请赐教： 如何同步？ 另外就代码本身而言，该如何修改？[/quote] 不是互斥的原因吧，这里貌似没有临界资源啊。 我跑了遍你的代码，运行输入时有时会出现死循环。是因为主进程中的free()释放出了问题导致主进程先退了，子进程读管道操作不在阻塞了，就不断的读啊读。造成死循环的现象。 主进程的代码申请空间后，没有清零吧。应该是溢出导致段错误。 楼主仔细看下这些代码是有问题的: char *numbers = (char*) malloc(len);             // concatenate two strings       strcpy(numbers, num1);       numbers[strlen(num1)]=' ';       //+ -> numbers[strlen(num1)+1]='\0';       strcat(numbers, num2);        [/quote]  应该不用加'\0' 这是strcat的解释：  char * strcat ( char * destination, const char * source ); Concatenate strings Appends a copy of the source string to the destination string. The terminating null character in destination is overwritten by the first character of source, and a null-character is included at the end of the new string formed by the concatenation of both in destination.  第二个string会把第一个string的null terminator覆盖掉。我在string中加入空格是为了把两个数字分开。。。  个人觉得应该是子进程在判断while循环的时候出了问题，read函数读到到字母，循环就会退出，等到下个循环开始，read又开始从之前的字母开始读。这是我的推测，但是我不清楚该如何解决这个问题。（如何清空read还没有读的剩下的内容，然后继续等待父进程的管道输入？）[/quote] 你试了增加那一句的代码么？ 如果你想增加空格，用strcat(numbers," ");不要覆盖结尾的’\0'。[/quote]  谢谢高手指点，好像运行暂时没有问题了。再多问个衍生的问题，如果我按ctrl+c结束了父进程，那么子进程会怎么样？变成孤儿进程，无止境的运行下去？

user: user-0
content: 引用 14 楼 shangyu0801 的回复:[quote=引用 8 楼 wanren13 的回复:] [quote=引用 5 楼 shangyu0801 的回复:] [quote=引用 2 楼 wanren13 的回复:] [quote=引用 1 楼 worldy 的回复:] 进程间读写没有同步？ 请赐教： 如何同步？ 另外就代码本身而言，该如何修改？[/quote] 不是互斥的原因吧，这里貌似没有临界资源啊。 我跑了遍你的代码，运行输入时有时会出现死循环。是因为主进程中的free()释放出了问题导致主进程先退了，子进程读管道操作不在阻塞了，就不断的读啊读。造成死循环的现象。 主进程的代码申请空间后，没有清零吧。应该是溢出导致段错误。 楼主仔细看下这些代码是有问题的: char *numbers = (char*) malloc(len);             // concatenate two strings       strcpy(numbers, num1);       numbers[strlen(num1)]=' ';       //+ -> numbers[strlen(num1)+1]='\0';       strcat(numbers, num2);        [/quote]  应该不用加'\0' 这是strcat的解释：  char * strcat ( char * destination, const char * source ); Concatenate strings Appends a copy of the source string to the destination string. The terminating null character in destination is overwritten by the first character of source, and a null-character is included at the end of the new string formed by the concatenation of both in destination.  第二个string会把第一个string的null terminator覆盖掉。我在string中加入空格是为了把两个数字分开。。。  个人觉得应该是子进程在判断while循环的时候出了问题，read函数读到到字母，循环就会退出，等到下个循环开始，read又开始从之前的字母开始读。这是我的推测，但是我不清楚该如何解决这个问题。（如何清空read还没有读的剩下的内容，然后继续等待父进程的管道输入？）[/quote] 你试了增加那一句的代码么？ 如果你想增加空格，用strcat(numbers," ");不要覆盖结尾的’\0'。[/quote] 谢谢，我试一下这个办法

user: user-0
content: 引用 13 楼 shangyu0801 的回复:[quote=引用 10 楼 lubyam 的回复:] [quote=引用 7 楼 shangyu0801 的回复:] [quote=引用 6 楼 lubyam 的回复:] [quote=引用 5 楼 shangyu0801 的回复:] [quote=引用 2 楼 wanren13 的回复:] [quote=引用 1 楼 worldy 的回复:] 进程间读写没有同步？ 请赐教： 如何同步？ 另外就代码本身而言，该如何修改？[/quote] 不是互斥的原因吧，这里貌似没有临界资源啊。 我跑了遍你的代码，运行输入时有时会出现死循环。是因为主进程中的free()释放出了问题导致主进程先退了，子进程读管道操作不在阻塞了，就不断的读啊读。造成死循环的现象。 主进程的代码申请空间后，没有清零吧。应该是溢出导致段错误。 楼主仔细看下这些代码是有问题的: char *numbers = (char*) malloc(len);             // concatenate two strings       strcpy(numbers, num1);       numbers[strlen(num1)]=' ';       //+ -> numbers[strlen(num1)+1]='\0';       strcat(numbers, num2);        [/quote]  子进程不是在管道有数据的时候就读取么？ 然后没有就阻塞吗？ 他写入进去了，子进程就读，这样应该没有问题把，。。。[/quote] 是啊，但是如果父进程退出了。会影响管道吧(ps:个人猜测，有待验证-:)。我试了，确实是因为父进程退出了，子进程的read就不受限制了。[/quote]  不是主进程的退出条件是写入管道失败，和用户强制结束么?  问以下你是怎么测试父进程退出的？[/quote]  exit ...[/quote]  主进程为什么会自己退出？ free的原因吗？ 但strcat的话应该是不用加'\0'的，按照strcat的解释

user: user-2
content: 引用 8 楼 wanren13 的回复:[quote=引用 5 楼 shangyu0801 的回复:] [quote=引用 2 楼 wanren13 的回复:] [quote=引用 1 楼 worldy 的回复:] 进程间读写没有同步？ 请赐教： 如何同步？ 另外就代码本身而言，该如何修改？[/quote] 不是互斥的原因吧，这里貌似没有临界资源啊。 我跑了遍你的代码，运行输入时有时会出现死循环。是因为主进程中的free()释放出了问题导致主进程先退了，子进程读管道操作不在阻塞了，就不断的读啊读。造成死循环的现象。 主进程的代码申请空间后，没有清零吧。应该是溢出导致段错误。 楼主仔细看下这些代码是有问题的: char *numbers = (char*) malloc(len);             // concatenate two strings       strcpy(numbers, num1);       numbers[strlen(num1)]=' ';       //+ -> numbers[strlen(num1)+1]='\0';       strcat(numbers, num2);        [/quote]  应该不用加'\0' 这是strcat的解释：  char * strcat ( char * destination, const char * source ); Concatenate strings Appends a copy of the source string to the destination string. The terminating null character in destination is overwritten by the first character of source, and a null-character is included at the end of the new string formed by the concatenation of both in destination.  第二个string会把第一个string的null terminator覆盖掉。我在string中加入空格是为了把两个数字分开。。。  个人觉得应该是子进程在判断while循环的时候出了问题，read函数读到到字母，循环就会退出，等到下个循环开始，read又开始从之前的字母开始读。这是我的推测，但是我不清楚该如何解决这个问题。（如何清空read还没有读的剩下的内容，然后继续等待父进程的管道输入？）[/quote] 你试了增加那一句的代码么？ 如果你想增加空格，用strcat(numbers," ");不要覆盖结尾的’\0'。

user: user-2
content: 引用 10 楼 lubyam 的回复:[quote=引用 7 楼 shangyu0801 的回复:] [quote=引用 6 楼 lubyam 的回复:] [quote=引用 5 楼 shangyu0801 的回复:] [quote=引用 2 楼 wanren13 的回复:] [quote=引用 1 楼 worldy 的回复:] 进程间读写没有同步？ 请赐教： 如何同步？ 另外就代码本身而言，该如何修改？[/quote] 不是互斥的原因吧，这里貌似没有临界资源啊。 我跑了遍你的代码，运行输入时有时会出现死循环。是因为主进程中的free()释放出了问题导致主进程先退了，子进程读管道操作不在阻塞了，就不断的读啊读。造成死循环的现象。 主进程的代码申请空间后，没有清零吧。应该是溢出导致段错误。 楼主仔细看下这些代码是有问题的: char *numbers = (char*) malloc(len);             // concatenate two strings       strcpy(numbers, num1);       numbers[strlen(num1)]=' ';       //+ -> numbers[strlen(num1)+1]='\0';       strcat(numbers, num2);        [/quote]  子进程不是在管道有数据的时候就读取么？ 然后没有就阻塞吗？ 他写入进去了，子进程就读，这样应该没有问题把，。。。[/quote] 是啊，但是如果父进程退出了。会影响管道吧(ps:个人猜测，有待验证-:)。我试了，确实是因为父进程退出了，子进程的read就不受限制了。[/quote]  不是主进程的退出条件是写入管道失败，和用户强制结束么?  问以下你是怎么测试父进程退出的？[/quote]  exit ...

user: user-0
content: 引用 11 楼 lubyam 的回复:[quote=引用 9 楼 wanren13 的回复:] [quote=引用 7 楼 shangyu0801 的回复:] [quote=引用 6 楼 lubyam 的回复:] [quote=引用 5 楼 shangyu0801 的回复:] [quote=引用 2 楼 wanren13 的回复:] [quote=引用 1 楼 worldy 的回复:] 进程间读写没有同步？ 请赐教： 如何同步？ 另外就代码本身而言，该如何修改？[/quote] 不是互斥的原因吧，这里貌似没有临界资源啊。 我跑了遍你的代码，运行输入时有时会出现死循环。是因为主进程中的free()释放出了问题导致主进程先退了，子进程读管道操作不在阻塞了，就不断的读啊读。造成死循环的现象。 主进程的代码申请空间后，没有清零吧。应该是溢出导致段错误。 楼主仔细看下这些代码是有问题的: char *numbers = (char*) malloc(len);             // concatenate two strings       strcpy(numbers, num1);       numbers[strlen(num1)]=' ';       //+ -> numbers[strlen(num1)+1]='\0';       strcat(numbers, num2);        [/quote]  子进程不是在管道有数据的时候就读取么？ 然后没有就阻塞吗？ 他写入进去了，子进程就读，这样应该没有问题把，。。。[/quote] 是啊，但是如果父进程退出了。会影响管道吧(ps:个人猜测，有待验证-:)。我试了，确实是因为父进程退出了，子进程的read就不受限制了。[/quote]  有什么办法可以解决这个问题吗？让父进程退出的时候，顺便也让子进程结束运行？[/quote] 用waitpid函数把，等待子进程结束[/quote]  如果wait的话，应该永远等不到子进程自己退出的那一天吧。。。？

user: user-4
content: 引用 9 楼 wanren13 的回复:[quote=引用 7 楼 shangyu0801 的回复:] [quote=引用 6 楼 lubyam 的回复:] [quote=引用 5 楼 shangyu0801 的回复:] [quote=引用 2 楼 wanren13 的回复:] [quote=引用 1 楼 worldy 的回复:] 进程间读写没有同步？ 请赐教： 如何同步？ 另外就代码本身而言，该如何修改？[/quote] 不是互斥的原因吧，这里貌似没有临界资源啊。 我跑了遍你的代码，运行输入时有时会出现死循环。是因为主进程中的free()释放出了问题导致主进程先退了，子进程读管道操作不在阻塞了，就不断的读啊读。造成死循环的现象。 主进程的代码申请空间后，没有清零吧。应该是溢出导致段错误。 楼主仔细看下这些代码是有问题的: char *numbers = (char*) malloc(len);             // concatenate two strings       strcpy(numbers, num1);       numbers[strlen(num1)]=' ';       //+ -> numbers[strlen(num1)+1]='\0';       strcat(numbers, num2);        [/quote]  子进程不是在管道有数据的时候就读取么？ 然后没有就阻塞吗？ 他写入进去了，子进程就读，这样应该没有问题把，。。。[/quote] 是啊，但是如果父进程退出了。会影响管道吧(ps:个人猜测，有待验证-:)。我试了，确实是因为父进程退出了，子进程的read就不受限制了。[/quote]  有什么办法可以解决这个问题吗？让父进程退出的时候，顺便也让子进程结束运行？[/quote] 用waitpid函数把，等待子进程结束

user: user-4
content: 引用 7 楼 shangyu0801 的回复:[quote=引用 6 楼 lubyam 的回复:] [quote=引用 5 楼 shangyu0801 的回复:] [quote=引用 2 楼 wanren13 的回复:] [quote=引用 1 楼 worldy 的回复:] 进程间读写没有同步？ 请赐教： 如何同步？ 另外就代码本身而言，该如何修改？[/quote] 不是互斥的原因吧，这里貌似没有临界资源啊。 我跑了遍你的代码，运行输入时有时会出现死循环。是因为主进程中的free()释放出了问题导致主进程先退了，子进程读管道操作不在阻塞了，就不断的读啊读。造成死循环的现象。 主进程的代码申请空间后，没有清零吧。应该是溢出导致段错误。 楼主仔细看下这些代码是有问题的: char *numbers = (char*) malloc(len);             // concatenate two strings       strcpy(numbers, num1);       numbers[strlen(num1)]=' ';       //+ -> numbers[strlen(num1)+1]='\0';       strcat(numbers, num2);        [/quote]  子进程不是在管道有数据的时候就读取么？ 然后没有就阻塞吗？ 他写入进去了，子进程就读，这样应该没有问题把，。。。[/quote] 是啊，但是如果父进程退出了。会影响管道吧(ps:个人猜测，有待验证-:)。我试了，确实是因为父进程退出了，子进程的read就不受限制了。[/quote]  不是主进程的退出条件是写入管道失败，和用户强制结束么?  问以下你是怎么测试父进程退出的？

user: user-0
content: 引用 7 楼 shangyu0801 的回复:[quote=引用 6 楼 lubyam 的回复:] [quote=引用 5 楼 shangyu0801 的回复:] [quote=引用 2 楼 wanren13 的回复:] [quote=引用 1 楼 worldy 的回复:] 进程间读写没有同步？ 请赐教： 如何同步？ 另外就代码本身而言，该如何修改？[/quote] 不是互斥的原因吧，这里貌似没有临界资源啊。 我跑了遍你的代码，运行输入时有时会出现死循环。是因为主进程中的free()释放出了问题导致主进程先退了，子进程读管道操作不在阻塞了，就不断的读啊读。造成死循环的现象。 主进程的代码申请空间后，没有清零吧。应该是溢出导致段错误。 楼主仔细看下这些代码是有问题的: char *numbers = (char*) malloc(len);             // concatenate two strings       strcpy(numbers, num1);       numbers[strlen(num1)]=' ';       //+ -> numbers[strlen(num1)+1]='\0';       strcat(numbers, num2);        [/quote]  子进程不是在管道有数据的时候就读取么？ 然后没有就阻塞吗？ 他写入进去了，子进程就读，这样应该没有问题把，。。。[/quote] 是啊，但是如果父进程退出了。会影响管道吧(ps:个人猜测，有待验证-:)。我试了，确实是因为父进程退出了，子进程的read就不受限制了。[/quote]  有什么办法可以解决这个问题吗？让父进程退出的时候，顺便也让子进程结束运行？

user: user-0
content: 引用 5 楼 shangyu0801 的回复:[quote=引用 2 楼 wanren13 的回复:] [quote=引用 1 楼 worldy 的回复:] 进程间读写没有同步？ 请赐教： 如何同步？ 另外就代码本身而言，该如何修改？[/quote] 不是互斥的原因吧，这里貌似没有临界资源啊。 我跑了遍你的代码，运行输入时有时会出现死循环。是因为主进程中的free()释放出了问题导致主进程先退了，子进程读管道操作不在阻塞了，就不断的读啊读。造成死循环的现象。 主进程的代码申请空间后，没有清零吧。应该是溢出导致段错误。 楼主仔细看下这些代码是有问题的: char *numbers = (char*) malloc(len);             // concatenate two strings       strcpy(numbers, num1);       numbers[strlen(num1)]=' ';       //+ -> numbers[strlen(num1)+1]='\0';       strcat(numbers, num2);        [/quote]  应该不用加'\0' 这是strcat的解释：  char * strcat ( char * destination, const char * source ); Concatenate strings Appends a copy of the source string to the destination string. The terminating null character in destination is overwritten by the first character of source, and a null-character is included at the end of the new string formed by the concatenation of both in destination.  第二个string会把第一个string的null terminator覆盖掉。我在string中加入空格是为了把两个数字分开。。。  个人觉得应该是子进程在判断while循环的时候出了问题，read函数读到到字母，循环就会退出，等到下个循环开始，read又开始从之前的字母开始读。这是我的推测，但是我不清楚该如何解决这个问题。（如何清空read还没有读的剩下的内容，然后继续等待父进程的管道输入？）

user: user-2
content: 引用 6 楼 lubyam 的回复:[quote=引用 5 楼 shangyu0801 的回复:] [quote=引用 2 楼 wanren13 的回复:] [quote=引用 1 楼 worldy 的回复:] 进程间读写没有同步？ 请赐教： 如何同步？ 另外就代码本身而言，该如何修改？[/quote] 不是互斥的原因吧，这里貌似没有临界资源啊。 我跑了遍你的代码，运行输入时有时会出现死循环。是因为主进程中的free()释放出了问题导致主进程先退了，子进程读管道操作不在阻塞了，就不断的读啊读。造成死循环的现象。 主进程的代码申请空间后，没有清零吧。应该是溢出导致段错误。 楼主仔细看下这些代码是有问题的: char *numbers = (char*) malloc(len);             // concatenate two strings       strcpy(numbers, num1);       numbers[strlen(num1)]=' ';       //+ -> numbers[strlen(num1)+1]='\0';       strcat(numbers, num2);        [/quote]  子进程不是在管道有数据的时候就读取么？ 然后没有就阻塞吗？ 他写入进去了，子进程就读，这样应该没有问题把，。。。[/quote] 是啊，但是如果父进程退出了。会影响管道吧(ps:个人猜测，有待验证-:)。我试了，确实是因为父进程退出了，子进程的read就不受限制了。

user: user-3
content: 刚帮你咨询了一下高手，从管道那里清除数据，没有这样的函数。 windows下的话，可以用closehandle解决这东西。

user: user-4
content: 引用 5 楼 shangyu0801 的回复:[quote=引用 2 楼 wanren13 的回复:] [quote=引用 1 楼 worldy 的回复:] 进程间读写没有同步？ 请赐教： 如何同步？ 另外就代码本身而言，该如何修改？[/quote] 不是互斥的原因吧，这里貌似没有临界资源啊。 我跑了遍你的代码，运行输入时有时会出现死循环。是因为主进程中的free()释放出了问题导致主进程先退了，子进程读管道操作不在阻塞了，就不断的读啊读。造成死循环的现象。 主进程的代码申请空间后，没有清零吧。应该是溢出导致段错误。 楼主仔细看下这些代码是有问题的: char *numbers = (char*) malloc(len);             // concatenate two strings       strcpy(numbers, num1);       numbers[strlen(num1)]=' ';       //+ -> numbers[strlen(num1)+1]='\0';       strcat(numbers, num2);        [/quote]  子进程不是在管道有数据的时候就读取么？ 然后没有就阻塞吗？ 他写入进去了，子进程就读，这样应该没有问题把，。。。

user: user-2
content: 引用 2 楼 wanren13 的回复:[quote=引用 1 楼 worldy 的回复:] 进程间读写没有同步？ 请赐教： 如何同步？ 另外就代码本身而言，该如何修改？[/quote] 不是互斥的原因吧，这里貌似没有临界资源啊。 我跑了遍你的代码，运行输入时有时会出现死循环。是因为主进程中的free()释放出了问题导致主进程先退了，子进程读管道操作不在阻塞了，就不断的读啊读。造成死循环的现象。 主进程的代码申请空间后，没有清零吧。应该是溢出导致段错误。 楼主仔细看下这些代码是有问题的: char *numbers = (char*) malloc(len);             // concatenate two strings       strcpy(numbers, num1);       numbers[strlen(num1)]=' ';       //+ -> numbers[strlen(num1)+1]='\0';       strcat(numbers, num2);