進程間的通信方式有五種,分別為:管道,信號量,共享內(nèi)存,消息隊列和套接字
管道
把一個程序的輸出直接連接在另外一個程序的輸入。
管道分為有名管道和無名管道兩種,它們的區(qū)別是:
無名管道只能在父子進程之間進行通信。
有名管道又稱為命名管道,可以在任意兩個進程之間進行通信。
1. 管道通信
1.1 通信模式
通信模式 | 通信特點 | 例子 |
---|---|---|
單工 | 數(shù)據(jù)只在一個方向上傳輸,不能實現(xiàn)雙方通信 | 電視、廣播 |
半雙工(切換的單工) | 允許數(shù)據(jù)在兩個方向上傳輸,但是同一時間數(shù)據(jù)只能在同一個方向上傳輸 | 對講機 |
全雙工 | 允許數(shù)據(jù)在兩個方向上同時傳輸 | 手機通話 |
1.2 管道通信中特殊的名詞
- 讀阻塞(進程阻塞):當(dāng)管道中沒有數(shù)據(jù)可讀時,會產(chǎn)生讀阻塞。
- 寫阻塞:當(dāng)管道已滿,再往管道中寫入數(shù)據(jù)時,會產(chǎn)生寫阻塞。直到有空間可以寫入時,再寫。
- 管道破裂:只有寫端,沒有讀端。
- 管道中不能使用lseek
2. 無名管道(PIPE)
是一種親緣進程間的通信方法
2.1 無名管道的通信原理
無名管道存在于kernel中,A,B必須具有親緣關(guān)系進程。同一時刻,只能有一個寫端或一個讀端。
- kernel的功能模塊
內(nèi)存管理單元(MMU)
主要負(fù)責(zé)物理內(nèi)存——>虛擬內(nèi)存空間的映射
內(nèi)存的開辟,釋放,存儲,讀取等一系列功能進程管理單元:
task(任務(wù))創(chuàng)建,管理和銷毀
任務(wù)調(diào)度策略:基于時間片的公平的輪轉(zhuǎn)策略
基于優(yōu)先級的搶占式任務(wù)調(diào)度策略文件系統(tǒng)
提供用戶訪問計算機資源的接口(軟件)
存儲,組織管理計算機文件和設(shè)備的軟件網(wǎng)絡(luò)管理
提供網(wǎng)絡(luò)通信協(xié)議棧
驅(qū)動模塊
硬件設(shè)備驅(qū)動
父子進程間,只要是fork()出來的,就會完美復(fù)制父進程的數(shù)據(jù)。如果在fork()之前創(chuàng)建管道,并獲取管道的操作接口,子進程就能使用管道。
2.2 無名管道特點
- 只能用于具有親緣關(guān)系的進程之間的通信(也就是父子進程和兄弟進程之間)。
- 是一個半雙工的通信方式,具有固定的讀端和寫端。
- 管道可以看做是一種特殊的文件,對管道的讀寫可以使用普通的read() ,write()函數(shù),但管道不屬于任何文件系統(tǒng)的,只存在于內(nèi)存中。
2.3 如何操作無名管道
- 創(chuàng)建
(pipe函數(shù)用來創(chuàng)建無名管道)- 操作
(read讀;write寫)- 關(guān)閉操作端口
(close)
示例1
本例引用于:http://blog.sina.com.cn/s/blog_5ed3e6210100d87d.html
https://blog.csdn.net/zggzgw/article/details/78120171
#include<unistd.h>
#include<stdio.h>
#include<string.h>
#include<sys/types.h>
#include<stdlib.h>
#include<sys/wait.h>
void read_pipe(int fd)
{
char message[100];
read(fd,message,100);
printf("read pipe message:%s",message);
}
void write_pipe(int fd)
{
char *message="this is Tuesday!\n";
write(fd,message,strlen(message)+1);
}
int main()
{
int fd[2];
pid_t pid;
int stat_val;
if(pipe(fd))
{
printf("create pipe failed!\n");
}
pid=fork();
switch(pid)
{
case -1:
printf("fork error!\n");
break;
case 0:
close(fd[1]);
read_pipe(fd[0]);
break;
default:
close(fd[0]);
write_pipe(fd[1]);
wait(&stat_val);
break;
}
}
示例2
本引用于自:
https://blog.csdn.net/yangxueyangxue/article/details/122336664
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(void)
{
char buf[32] = {0};
pid_t pid;
// 定義一個變量來保存文件描述符
// 因為一個讀端, 一個寫端, 所以數(shù)量為 2 個
int fd[2];
// 創(chuàng)建無名管道
pipe(fd);
printf("fd[0] is %d\n", fd[0]);
printf("fd[2] is %d\n", fd[1]);
// 創(chuàng)建進程
pid = fork();
if (pid < 0)
{
printf("error\n");
}
if (pid > 0)
{
int status;
close(fd[0]);
write(fd[1], "hello", 5);
close(fd[1]);
wait(&status);
exit(0);
}
if (pid == 0)
{
close(fd[1]);
read(fd[0], buf, 32);
printf("buf is %s\n", buf);
close(fd[0]);
exit(0);
}
return 0;
}
3. 有名管道(FIFO)
是對無名管道的一種改進
3.1 有名管道的特點
- 它可以使互不相關(guān)的兩個進程實現(xiàn)彼此通信
- 該管道可以通過路徑名來指出,并且在文件系統(tǒng)中是可見的。在建立管道之后,兩個進程就可以把它當(dāng)作普通文件進行讀寫,使用非常方便。
- FIFO嚴(yán)格遵循先進先出原則,對管道及FIFO的讀總是從開始處返回數(shù)據(jù),對它們的寫則把數(shù)據(jù)添加到末尾。有名管道不支持如Iseek()等文件的定位操作。
- 有名管道依然在內(nèi)核態(tài)內(nèi)存中
- 有名管道在文件系統(tǒng)中有節(jié)點(即在跟文件系統(tǒng)中可以找到)
- 有名管道的大小始終為0
- 有名管道的文件類型為p
- 有名管道嚴(yán)格遵循先進先出原則
- 有名管道不能使用文件重定位的函數(shù)Iseek
- 有名管道可以用在親緣和非親緣進程間(一般用于非親緣進程間通信)
3.2 如何操作有名管道
- 創(chuàng)建有名管道文件
(mkfifo即是命令也是函數(shù);mknod也可以創(chuàng)建管道文件)- 打開有名管道
(open)- 讀/寫
(read/write)- 關(guān)閉
(close)
本例引用于:
https://blog.csdn.net/yangxueyangxue/article/details/122336664
write01.c
創(chuàng)建兩個無關(guān)聯(lián)的進程, 一個進程創(chuàng)建有名管道并寫數(shù)據(jù), 另一個進程通過管道讀數(shù)據(jù)。
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char *argv[])
{
int ret;
char buf[32] = {0};
int fd;
if (argc < 2)
{
printf("Usage:%s <fifo name> \n", argv[0]);
return -1;
}
if (access(argv[1], F_OK) == -1)
{
ret = mkfifo(argv[1], 0666);
if (ret == -1)
{
printf("mkfifo is error \n");
return -2;
}
printf("mkfifo is ok \n");
}
fd = open(argv[1], O_WRONLY);
while (1)
{
sleep(1);
write(fd, "hello", 5);
}
close(fd);
return 0;
}
read01.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main(int argc, char *argv[])
{
char buf[32] = {0};
int fd;
if (argc < 2)
{
printf("Usage:%s <fifo name> \n", argv[0]);
return -1;
}
fd = open(argv[1], O_RDONLY);
while (1)
{
sleep(1);
read(fd, buf, 32);
printf("buf is %s\n", buf);
memset(buf, 0, sizeof(buf));
}
close(fd);
return 0;
}
4. 示例
以下示例引用于:
https://blog.csdn.net/zsy3757486/article/details/126765536
4.1 cut
根據(jù)條件 從命令結(jié)果中提取對應(yīng)內(nèi)容
4.1.1 截取出1.txt中前1行的第2個字符
head -1 1.txt | cut -c 2
參數(shù) | 含義 |
---|---|
-c | 按字符選取內(nèi)容 |
4.1.2 截取出指定文件中前n行以”:”進行分割的第n1,n2段內(nèi)容
head -n 文件名 | cut -d ':' -f n1,n2
OR(或者)
head -n 文件名 | cut -d ':' -f n1-n2
范圍控制 | 含義 |
---|---|
n | 只顯示第 n 段 |
n- | 顯示從第 n 段一直到行尾 |
n1-n2 | 顯示從第 n1 段到 n2 段 |
4.1.2.1 截取出2.txt中前2行以”:”進行分割的第1,2段內(nèi)容
head -2 2.txt | cut -d ':' -f 1,2
參數(shù) | 含義 |
---|---|
-d | 指定分隔符 |
-f | 顯示指定段落內(nèi)容 |
4.1.2.2 截取出指定文件中前4行以”:”進行分割的第1,2,3,4段內(nèi)容
head -4 2.txt | cut -d ':' -f 1-4
4.2 wc
4.3 uniq
4.4 tee
4.5 tr
其下皆由此引用:
https://blog.csdn.net/qq_45171957/article/details/123698265
4.6 生成一個8位的隨機密碼
tr -dc A-Za-z0-9_ </dev/urandom | head -c 8 | xargs
4.7 查看系統(tǒng)中所有的用戶名稱,并按字母排序
awk -F: '{print $1}' /etc/passwd | sort
4.8 列出當(dāng)前用戶使用最多的5個命令(print的列數(shù)根據(jù)實際情況而定)
history | awk '{print $2}' | sort | uniq -u | sort -rn | head -5
4.9 查看系統(tǒng)中有哪些用戶的登陸shell時/bin/bash
cat /etc/passwd | grep "/bin/bash" | cut -d: -f1,6
cut -d: -f1,6 表示以:為分隔符顯示第1和第6列的內(nèi)容-d指定分隔符,-f指定列
4.10 查看當(dāng)前目錄的子目錄個數(shù)
ls -l | cut -c 1 | grep "d" | wc -l
ls -l 長格式列出當(dāng)前目錄的所有內(nèi)容,每行的第一個字符表示文件的類
cut -c 1 截取每行的第一個字符
grep “d” 獲取文件類型是目錄的行
wc -l 統(tǒng)計grep命令輸出的行數(shù),即子目錄個數(shù)
4.11 合并兩個文件的內(nèi)容
cat 1.txt | paste -d: 2.txt -
paste -d: 2.txt - 表示以:為分割符合并兩個文件,合并時2.txt文件的內(nèi)容在前
-代表1.txt文件文章來源:http://www.zghlxwxcb.cn/news/detail-479245.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-479245.html
到了這里,關(guān)于【嵌入式總復(fù)習(xí)】Linux管道詳解——管道通信、無名管道、有名管道、具體應(yīng)用示例的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!