歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Linux 進程通信(System V)

簡介:

一.
#include <unistd.h>

int pipe(int fd[2]);    //!>注意參數是fd[0]是讀的文件描述符,fd[1]是用來寫的文件描述符

一般用於 “父子進程” 之間的通信!因為pipe是沒有標志的,所以只能在一個進程集中運作!

“單向pipe”:
      父進程創建好 pipe 後,同時通過 fork() 創建一個子進程,然後父進程就可以關閉自己這端的“讀進程”,因為  父進程就是將數據寫入子進程的,所以無須 “讀”,然後子進程就關閉自己的“寫”,這樣就形成一個 “單向” 的 pipe。

“雙向pie”:( 可以用於CS )
     創建兩個pipe就可以了,其實也就是相當於加一個 “單向”pipe

二.
    關於 fork函數
    對於fork的返回值:對於父進程返回的是子進程的ID號(肯定是大於0的),對於子進程返回的是0
所以可以通過 if( pid = fork() > 0 ) 和 if( pid == 0 )來判斷是父進程還是子進程在執行

三.
    其他
    對於 pipe而言,創建 ok後,在子進程和父進程中都會有一個此管道(pipe)的讀和寫的接口!操作value是相同的fd[0]和fd[1]

對於 test.c 中的為例:
      由於是多進程編程,那麼對於test.c代碼而言,應該是有“子進程”和“父進程”都可以執行的!也就是說在fork後程序就是分成兩部分,主進程和子進程。
      我們可以測試:
       如果是printf("on ");那麼可以輸出兩次 on,分別是父進程和子進程輸出的,但是if是printf(" on \n");那麼只輸出一次。
      原因:printf的機制是:遇到"\n"就會直接輸出,if沒有,那麼只是儲存在緩存中,然後一起輸出。
         所以if有"\n",那麼就是父進程先讓其輸出了,那麼在父進程的空間空就沒有保存printf中的緩存數據了!!!所以子進程就沒有繼承到,所以就不會輸出!!!
         
       也就是說:父進程的printf 空間緩存區也被繼承!!!!!!!!!!!!!!!!!!!!!

       getpid():獲得本進程的ID
       getppid():獲得父進程的ID   

四.參考代碼:

//!>
//!> 單向 pipe實例   
//!>

#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>

int g_num =0;               //!> 全局變量:用來測試父進程和子進程的獨立空間
                  //!> 我們可以知道全局變量在子進程和父進程中是有自己的獨立空間的!
int main()
{
    int n,fd[2];            //!> fd 是描述符
    pid_tpid;            //!> 保存的是創建的進程的 ID
    charline[100];            //!> 相當於是一個緩存

    int num = 0;            //!> 也是獨立的~~~

    printf(" on");            //!> ATTENTION  printf(" on\n");

    if( pipe( fd) < 0)         //!> 此處就是創建pipe,成功則返回0,if失敗則返回-1
    {
      exit(0);
    }

   
    if( ( pid =fork() ) < 0)      //!> 創建子進程
    {
      exit(0);
    }
    else if( pid> 0 )
    {
      close(fd[0]);
       write(fd[1],"I am your father...\n", 19);
      
      g_num++;
       num++;
      printf("\nFather g_num:%d    num: %d\n", g_num,num);   

       printf("\nMYID : %d   Parent ID : %d  \n", getpid(), getcpid());
    }
   else               //!> == 0 當前進程(也就是剛剛創建的子進程)
    {
       close( fd[1]);
       n = read(fd[0], line, 100 );
       write(STDOUT_FILENO, line, n );    //

      g_num++;
       num++;
      printf("\nChild g_num:%d    num: %d\n", g_num, num);

       printf("\nMYID : %d   Parent ID : %d  \n", getpid(), getppid());
    }

    printf(" ok");            
   
    return0;
}


//!>
//!> 雙向 pipe 實例
//!>

#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main()
{
    int fd_1[2],fd_2[2];                  //!> 雙向 pipe 的 values、
    charcData[100];
    pid_tpid;
   
    if( pipe(fd_1 ) < 0)                  //!> create the pipe_1
    {
      printf("\n創建第一個 pipe 失敗!\n");
       exit( 0);
    }
   
    if( pipe(fd_2 ) < 0)               //!> create the pipe_2
    {
      printf("\n創建第二個 pipe 失敗!\n");
       exit( 0);
    }

    if( ( pid =fork() ) < 0)               //!> false to create a new process
    {
      printf("\n創建進程失敗!\n");
       exit( 0);
    }
    else if( pid== 0 )                  //!> 也就是fork返回的子進程...
    {
      //!> 子進程也需要發送 data 到 pipe
       close(fd_2[0] );
       char str[30]= "I am your child!";
       write(fd_2[1], str, strlen( str ));      //!> 第二個pipe是子進程發送data,父進程接受data
      
      //!> 子進程也需要接受父進程的 data
       close(fd_1[1] );
       int n =read( fd_1[0], cData, 100);      //!> 第一個pipe是父進程發送data,子進程接受data
       write(STDOUT_FILENO, cData, n );
    }
   else                        //!> fork 返回的是子進程的ID,肯定是大於0的,所以此處執行的是父進程的code
    {
      //!> 父進程也需要發送 data 到 pipe
       close(fd_1[0] );
       char str[30]= "I am your father!";
       write(fd_1[1], str, strlen( str ));      //!> 第二個pipe是子進程發送data,父進程接受data
      
      //!> 父進程也需要接受父進程的 data
      close(fd_2[1] );
       int n =read( fd_2[0], cData, 100);      //!> 第一個pipe是父進程發送data,子進程接受data
       write(STDOUT_FILENO, cData, n );
    }

    return0;
}
Copyright © Linux教程網 All Rights Reserved