歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Linux 進程通信(System V)

Linux 進程通信(System V)

日期:2017/3/1 10:26:01   编辑:Linux編程
簡介:

一.
#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