今天主要學習了進程間的通信,主要學習了通過管道進行通信
一、進程間的通信
進程間的通信方式有以下幾種:
1.管道
2.信號
3.消息隊列
4.共享內存
5.信號燈
6.套接字
二、管道
2.1無名管道
無名管道只能用于具有親緣關系的進程間通信
函數接口:pipeint pipe(int pipefd[2]);功能:創建一個無名管道參數:pipefd[0]:讀管道文件描述符pipefd[1]:寫管道文件描述符返回值:成功返回0 失敗返回-1 無名管道特性:1.管道中至少有一個寫端: 讀取數據時,如果管道中有數據直接讀取,管道中沒有數據阻塞等待直到有數據寫入讀出,繼續向后執行2.管道中沒有寫端:讀取數據時,如果管道中有數據直接讀取,管道中沒有數據不阻塞等待直接向下執行3.管道中至少有一個讀端:寫入數據時,如果管道中沒有存滿(64k),則直接寫入,管道中如果存滿,則阻塞等待直到有數據讀出,才能繼續寫入4.管道中沒有讀端:寫入數據時,會產生管道破裂錯誤,導致程序崩潰
通過無名管道通信的實例:
#include "head.h"int main(void)
{pid_t pid;int fd[2];int ret = 0;int cnt = 0;char tmpbuff[4096] = {0};ret = pipe(fd);if (-1 == ret){perror("fail to pipe");return -1;}pid = fork();if (-1 == pid){perror("fail to fork");return -1;}if (0 == pid){close(fd[0]);strcpy(tmpbuff, "hello world");while (1){write(fd[1], tmpbuff, sizeof(tmpbuff));cnt++;printf("cnt = %d\n", cnt);}}else if (pid > 0){close(fd[0]);sleep(5);read(fd[0], tmpbuff, sizeof(tmpbuff));}while (1){}return 0;
}
2.2有名管道
打開管道文件 -> 讀寫管道文件 -> 關閉管道文件注意:有名管道必須讀寫兩端同時加入才能繼續向下執行1.mkfifo int mkfifo(const char *pathname, mode_t mode);功能:創建一個管道文件參數:pathname:管道文件路徑mode:權限返回值:成功返回0 失敗返回-1
使用實例:
#include "head.h"int fatob = 0;
int fbtoa = 0;
pthread_t tid_send;
pthread_t tid_recv;void *sendfun(void *arg)
{ char tmpbuff[1024] = {0};while (1){memset(tmpbuff, 0, sizeof(tmpbuff));gets(tmpbuff);write(fatob, tmpbuff, strlen(tmpbuff));if (!strcmp(tmpbuff, ".quit")){break;}}pthread_cancel(tid_recv);return NULL;
}void *recvfun(void *arg)
{char tmpbuff[1024] = {0};while (1){memset(tmpbuff, 0, sizeof(tmpbuff));read(fbtoa, tmpbuff, sizeof(tmpbuff));if (!strcmp(tmpbuff, ".quit")){break;}printf("RECV:%s\n", tmpbuff);}pthread_cancel(tid_send);return NULL;
}int main(void)
{char tmpbuff[1024] = {0};mkfifo("/tmp/ATOB", 0777);mkfifo("/tmp/BTOA", 0777);fatob = open("/tmp/ATOB", O_WRONLY);if (-1 == fatob){perror("fail to open");return -1;}fbtoa = open("/tmp/BTOA", O_RDONLY);if (-1 == fbtoa){perror("fail to open");return -1;}pthread_create(&tid_send, NULL, sendfun, NULL);pthread_create(&tid_recv, NULL, recvfun, NULL);pthread_join(tid_send, NULL);pthread_join(tid_recv, NULL);close(fatob);close(fbtoa);return 0;
}
三、信號
信號用來實現內核層和用戶層信息的交互,也可以用來實現進程間通信
1.信號的種類:
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR111) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+338) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+843) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+1348) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-1253) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-758) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-263) SIGRTMAX-1 64) SIGRTMAX
2.信號處理方式:
1.缺省:按照系統默認的方式處理2.忽略:不響應信號3.捕捉:按照自定義方式處理信號9號信號SIGKILL19號信號SIGSTOP 這兩個信號不能被忽略和捕捉以下三個信號可以從鍵盤輸入:SIGINT:ctrl + c SIGQUIT:ctrl + \SIGTSTP:ctrl + z4.signal typedef void (*sighandler_t)(int);sighandler_t signal(int signum, sighandler_t handler);功能:改變信號的處理方式參數:signum:信號的編號handler:信號的處理方式SIG_IGN 忽略處理SIG_DFL 缺省處理函數首地址 捕捉處理返回值:成功返回之前處理函數的首地址失敗返回SIG_ERR