Linux命名管道方式
一、命名管道
1、與匿名管道的關(guān)系
命名管道由mkfifo創(chuàng)建,是一個(gè)文件,打開(kāi)要用open打開(kāi)
命名管道與匿名管道之間唯一的區(qū)別就是它們創(chuàng)建和打開(kāi)的方式不同,其他基本上相同
命名管道也只能和有“血緣”的進(jìn)程進(jìn)行通信
2、工作原理
通過(guò)mkfifo創(chuàng)建,會(huì)生成一個(gè)文件,這就是我們的命名管道文件,它的大小為0

可以看到它的第一列為p,說(shuō)明它是特殊文件
在我們對(duì)普通文件進(jìn)行打開(kāi)的時(shí)候,我們要進(jìn)行的結(jié)構(gòu)其實(shí)是這樣的

其中這個(gè)刷盤(pán)的過(guò)程就是文件緩沖區(qū)中的數(shù)據(jù)刷新到硬盤(pán)上的過(guò)程,而我們的fifo文件即命名管道文件是沒(méi)有刷盤(pán)的,所以數(shù)據(jù)只會(huì)待在文件緩沖區(qū)里,因?yàn)樵贚inux中,多個(gè)進(jìn)程打開(kāi)同一個(gè)文件所指向的文件緩沖區(qū)只有一個(gè),所以如果此時(shí)再有一個(gè)進(jìn)程以讀方式打開(kāi)fifo文件,它們之間就會(huì)以文件緩沖區(qū)作為紐帶連接,形成了一個(gè)結(jié)構(gòu),這個(gè)結(jié)構(gòu),與我們以前所講的匿名管道形成的管道結(jié)構(gòu)是一摸一樣的
3、系統(tǒng)調(diào)用接口
#include <sys/types.h> #include <sys/stat.h> int mkfifo(const char *filename, mode_t mode); // filename:文件路徑 // mode:文件權(quán)限 // 返回值:如果管道創(chuàng)建成功返回0,如果失敗返回-1并設(shè)置errno
4、實(shí)現(xiàn)兩個(gè)進(jìn)程間通信
- tests.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#define FIFO_NAME "myfifo"
#define BUFFER_SIZE 256
int main()
{
char message[BUFFER_SIZE];
// 創(chuàng)建命名管道
if (mkfifo(FIFO_NAME, 0666) == -1)
{
if (errno != EEXIST)
{
perror("mkfifo");
return 1;
}
}
// 打開(kāi)命名管道以進(jìn)行寫(xiě)入操作
int fd = open(FIFO_NAME, O_WRONLY);
if (fd == -1)
{
perror("open");
return 1;
}
// 獲取用戶(hù)輸入的消息
while (1)
{
printf("Enter a message to send: ");
fgets(message, BUFFER_SIZE, stdin);
message[strcspn(message, "\n")] = 0; // 移除換行符
// 向命名管道寫(xiě)入消息
if (write(fd, message, strlen(message)) == -1)
{
perror("write");
close(fd);
return 1;
}
printf("Message sent successfully.\n");
}
// 關(guān)閉命名管道
close(fd);
return 0;
}- testr.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define FIFO_NAME "myfifo"
#define BUFFER_SIZE 256
int main()
{
int fd;
char buffer[BUFFER_SIZE];
// 打開(kāi)命名管道以進(jìn)行讀取操作
fd = open(FIFO_NAME, O_RDONLY);
if (fd == -1)
{
perror("open");
return 1;
}
while (1)
{
// 從命名管道讀取消息
ssize_t bytes_read = read(fd, buffer, BUFFER_SIZE - 1);
if (bytes_read == -1)
{
perror("read");
close(fd);
return 1;
}
buffer[bytes_read] = '\0'; // 添加字符串結(jié)束符
// 輸出接收到的消息
if(buffer[0] == 0) break;
printf("Received message: %s\n", buffer);
}
// 關(guān)閉命名管道
close(fd);
// 刪除命名管道
if (unlink(FIFO_NAME) == -1)
{
perror("unlink");
return 1;
}
return 0;
}二、可變參數(shù)列表
我們后面要借助命名管道來(lái)寫(xiě)一個(gè)日志文件,我們需要用到可變參數(shù)列表的知識(shí),在這里詳細(xì)解釋一下
可變參數(shù)列表允許函數(shù)接受不定數(shù)量和類(lèi)型的參數(shù),一般在使用時(shí)放到最后面,例如我們前面在進(jìn)程中斷中的函數(shù):
int execl(const char *path, const char *arg, ...);
我們現(xiàn)在有“表”的概念,只要是一個(gè)表,最后一個(gè)元素一定是NULL,來(lái)標(biāo)志著這個(gè)表的結(jié)束
與其相關(guān)的關(guān)鍵元素有以下四個(gè):(頭文件stdarg.h)
va_list:va_list 是一種自定義類(lèi)型(通常為指針類(lèi)型),用于聲明一個(gè)變量,該變量將指向可變參數(shù)列表va_start宏:其作用是初始化 va_list 類(lèi)型的變量,讓它指向可變參數(shù)列表的第一個(gè)參數(shù)
void va_start(va_list ap, last); //ap:va_list 類(lèi)型的變量 //last:可變參數(shù)列表之前的最后一個(gè)固定參數(shù)
va_arg宏:此宏用于從可變參數(shù)列表中獲取下一個(gè)參數(shù),并將 va_list 指針移動(dòng)到下一個(gè)參數(shù)的位置
type va_arg(va_list ap, type); //ap:va_list 類(lèi)型的變量 //type:要獲取的參數(shù)的類(lèi)型
va_end宏:該宏用于結(jié)束對(duì)可變參數(shù)列表的訪(fǎng)問(wèn),進(jìn)行必要的清理工作
void va_end(va_list ap); //ap:之前用 va_start 初始化過(guò)的 va_list 變量
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
crontab執(zhí)行結(jié)果未通過(guò)發(fā)送mail通知用戶(hù)的方法
這篇文章主要給大家介紹了關(guān)于crontab執(zhí)行結(jié)果未通過(guò)發(fā)送mail通知用戶(hù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用linux系統(tǒng)具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06
Linux網(wǎng)絡(luò)配置和監(jiān)控命令總結(jié)
本文介紹了Linux系統(tǒng)中常用的網(wǎng)絡(luò)配置和監(jiān)控命令,包括ifconfig、hostname、route、netstat、ss、lsof、ping、traceroute、nslookup等命令的使用方法和作用,適用于系統(tǒng)管理員在日常管理和故障排查中的網(wǎng)絡(luò)操作2024-09-09
Linux使用 iftop 實(shí)時(shí)監(jiān)控網(wǎng)卡的流量
iftop可以用來(lái)監(jiān)控網(wǎng)卡的實(shí)時(shí)流量(可以指定網(wǎng)段)、反向解析IP、顯示端口信息等。這篇文章主要介紹了Linux 實(shí)時(shí)網(wǎng)卡流量監(jiān)控,需要的朋友可以參考下2019-11-11
Linux靜態(tài)庫(kù)與動(dòng)態(tài)庫(kù)實(shí)例詳解
這篇文章主要介紹了 Linux靜態(tài)庫(kù)與動(dòng)態(tài)庫(kù)實(shí)例詳解的相關(guān)資料,希望通過(guò)本文能幫助到大家,讓大家理解掌握這部分內(nèi)容,需要的朋友可以參考下2017-10-10
Linux上定位后臺(tái)服務(wù)偶發(fā)崩潰的解決方法
在本篇內(nèi)容中小編給大家整理的是一篇關(guān)于Linux上定位后臺(tái)服務(wù)偶發(fā)崩潰的解決方法,有需要的朋友們可以學(xué)習(xí)參考下。2020-11-11
在Linux中如何查看可用的網(wǎng)絡(luò)接口詳解
這篇文章主要給大家介紹了關(guān)于在Linux中如何查看可用的網(wǎng)絡(luò)接口的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Linux具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03

