Linux命名管道方式
一、命名管道
1、與匿名管道的關(guān)系
命名管道由mkfifo
創(chuàng)建,是一個(gè)文件,打開要用open打開
命名管道與匿名管道之間唯一的區(qū)別就是它們創(chuàng)建和打開的方式不同,其他基本上相同
命名管道也只能和有“血緣”的進(jìn)程進(jìn)行通信
2、工作原理
通過mkfifo
創(chuàng)建,會(huì)生成一個(gè)文件,這就是我們的命名管道文件,它的大小為0
可以看到它的第一列為p,說(shuō)明它是特殊文件
在我們對(duì)普通文件進(jìn)行打開的時(shí)候,我們要進(jìn)行的結(jié)構(gòu)其實(shí)是這樣的
其中這個(gè)刷盤的過程就是文件緩沖區(qū)中的數(shù)據(jù)刷新到硬盤上的過程,而我們的fifo文件即命名管道文件是沒有刷盤的,所以數(shù)據(jù)只會(huì)待在文件緩沖區(qū)里,因?yàn)樵贚inux中,多個(gè)進(jìn)程打開同一個(gè)文件所指向的文件緩沖區(qū)只有一個(gè),所以如果此時(shí)再有一個(gè)進(jìn)程以讀方式打開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; } } // 打開命名管道以進(jìn)行寫入操作 int fd = open(FIFO_NAME, O_WRONLY); if (fd == -1) { perror("open"); return 1; } // 獲取用戶輸入的消息 while (1) { printf("Enter a message to send: "); fgets(message, BUFFER_SIZE, stdin); message[strcspn(message, "\n")] = 0; // 移除換行符 // 向命名管道寫入消息 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]; // 打開命名管道以進(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)寫一個(gè)日志文件,我們需要用到可變參數(shù)列表的知識(shí),在這里詳細(xì)解釋一下
可變參數(shù)列表允許函數(shù)接受不定數(shù)量和類型的參數(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 是一種自定義類型(通常為指針類型),用于聲明一個(gè)變量,該變量將指向可變參數(shù)列表va_start
宏:其作用是初始化 va_list 類型的變量,讓它指向可變參數(shù)列表的第一個(gè)參數(shù)
void va_start(va_list ap, last); //ap:va_list 類型的變量 //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 類型的變量 //type:要獲取的參數(shù)的類型
va_end
宏:該宏用于結(jié)束對(duì)可變參數(shù)列表的訪問,進(jìn)行必要的清理工作
void va_end(va_list ap); //ap:之前用 va_start 初始化過的 va_list 變量
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
crontab執(zhí)行結(jié)果未通過發(fā)送mail通知用戶的方法
這篇文章主要給大家介紹了關(guān)于crontab執(zhí)行結(jié)果未通過發(fā)送mail通知用戶的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用linux系統(tǒng)具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06Linux網(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-09Linux使用 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-11Linux靜態(tài)庫(kù)與動(dòng)態(tài)庫(kù)實(shí)例詳解
這篇文章主要介紹了 Linux靜態(tài)庫(kù)與動(dòng)態(tài)庫(kù)實(shí)例詳解的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解掌握這部分內(nèi)容,需要的朋友可以參考下2017-10-10Linux上定位后臺(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)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Linux具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03