優(yōu)秀電商設(shè)計(jì)網(wǎng)站有哪些內(nèi)容南昌網(wǎng)站建設(shè)方案外包
鶴壁市浩天電氣有限公司
2026/01/24 11:08:32
優(yōu)秀電商設(shè)計(jì)網(wǎng)站有哪些內(nèi)容,南昌網(wǎng)站建設(shè)方案外包,新老網(wǎng)站做301跳轉(zhuǎn),國(guó)開(kāi)機(jī)考網(wǎng)站界面設(shè)計(jì)一、管道#xff08;Pipe#xff09;1. 基本概念管道是一種半雙工的通信方式#xff0c;數(shù)據(jù)只能單向流動(dòng)。只能在具有親緣關(guān)系的進(jìn)程之間使用。管道本質(zhì)上是一個(gè)內(nèi)核緩沖區(qū)#xff0c;通過(guò)文件描述符進(jìn)行讀寫(xiě)操作。包括讀端 fd[0] 和寫(xiě)端 fd[1]。2. 創(chuàng)建管道int fd[2];
pi…一、管道Pipe1. 基本概念管道是一種半雙工的通信方式數(shù)據(jù)只能單向流動(dòng)。只能在具有親緣關(guān)系的進(jìn)程之間使用。管道本質(zhì)上是一個(gè)內(nèi)核緩沖區(qū)通過(guò)文件描述符進(jìn)行讀寫(xiě)操作。包括讀端fd[0]和寫(xiě)端fd[1]。2. 創(chuàng)建管道int fd[2]; pipe(fd);3. 讀阻塞Read Blocking如果管道為空讀操作會(huì)阻塞直到有數(shù)據(jù)寫(xiě)入。示例代碼#include stdio.h #include stdlib.h #include unistd.h #include string.h int main(int argc, char **argv) { int fd[2]{0}; int ret pipe(fd); if(-1 ret) { perror(pipe error
); return 1; } pid_t pid fork(); if(pid0) { close(fd[0]); int i 3; while(i--) { printf(father 準(zhǔn)備數(shù)據(jù)
); sleep(1); } char buf[1024]hello ,son; write(fd[1],buf,strlen(buf)); close(fd[1]); } else if(0 pid) { close(fd[1]); char buf[1024]{0}; // 讀阻塞 示例 read(fd[0],buf,sizeof(buf)); printf(father say:%s
,buf); close(fd[0]); } else { perror(fork); return 1; } return 0; }子進(jìn)程調(diào)用read時(shí)父進(jìn)程尚未寫(xiě)入數(shù)據(jù)子進(jìn)程阻塞等待。父進(jìn)程睡眠3秒后寫(xiě)入數(shù)據(jù)子進(jìn)程才繼續(xù)執(zhí)行。4. 寫(xiě)阻塞Write Blocking如果管道緩沖區(qū)滿(mǎn)寫(xiě)操作會(huì)阻塞直到有空間寫(xiě)入。示例代碼#include stdio.h #include stdlib.h #include unistd.h #include string.h int main(int argc, char **argv) { int fd[2]{0}; int ret pipe(fd); if(-1 ret) { perror(pipe error
); return 1; } pid_t pid fork(); if(pid0) { close(fd[0]); char buf[1024]{0}; memset(buf,a,sizeof(buf)); int i 0 ; // 寫(xiě)阻塞 示例 for(i0;i65;i) { write(fd[1],buf,sizeof(buf)); printf(%d
,i); } close(fd[1]); } else if(0 pid) { close(fd[1]); while(1) { sleep(1); } close(fd[0]); } else { perror(fork); return 1; } return 0; }父進(jìn)程循環(huán)寫(xiě)入數(shù)據(jù)直到管道滿(mǎn)后續(xù)寫(xiě)入會(huì)阻塞。子進(jìn)程不讀數(shù)據(jù)導(dǎo)致寫(xiě)端持續(xù)阻塞。5. 管道破裂Broken Pipe當(dāng)讀端關(guān)閉寫(xiě)端繼續(xù)寫(xiě)入時(shí)會(huì)觸發(fā)SIGPIPE信號(hào)默認(rèn)行為是終止進(jìn)程。示例代碼#include stdio.h #include stdlib.h #include string.h #include unistd.h int main(int argc, char **argv) { int fd[2] {0}; int ret pipe(fd); if (-1 ret) { perror(pipe error
); return 1; } pid_t pid fork(); if (pid 0) { close(fd[0]); sleep(3); char buf[1024] hello ,son; //管道破裂 gdb 查看 //Program received signal SIGPIPE, Broken pipe write(fd[1], buf, strlen(buf)); printf(--------------
); close(fd[1]); } else if (0 pid) { close(fd[1]); close(fd[0]); exit(1); } else { perror(fork); return 1; } return 0; }子進(jìn)程關(guān)閉了讀端父進(jìn)程寫(xiě)入數(shù)據(jù)時(shí)觸發(fā)管道破裂。6. 讀取管道結(jié)束EOF當(dāng)寫(xiě)端關(guān)閉讀端讀取完所有數(shù)據(jù)后read返回0表示管道結(jié)束。示例代碼#include stdio.h #include stdlib.h #include string.h #include unistd.h int main(int argc, char **argv) { int fd[2] {0}; int ret pipe(fd); if (-1 ret) { perror(pipe error
); return 1; } pid_t pid fork(); if (pid 0) { close(fd[0]); char buf[1024] hello ,son; write(fd[1], buf, strlen(buf)); close(fd[1]); exit(0); } else if (0 pid) { close(fd[1]); sleep(3); while (1) { char buf[1024] {0}; int ret read(fd[0], buf, sizeof(buf)); // ret 0 enf of pipe if(ret0) { break; } printf(father say:%s
, buf); } close(fd[0]); } else { perror(fork); return 1; } return 0; }父進(jìn)程寫(xiě)入數(shù)據(jù)后關(guān)閉寫(xiě)端。子進(jìn)程讀取數(shù)據(jù)當(dāng)read返回0時(shí)退出循環(huán)。7. 管道復(fù)制文件管道可用于父子進(jìn)程間傳遞大量數(shù)據(jù)如文件復(fù)制。示例代碼#include fcntl.h #include stdio.h #include stdlib.h #include string.h #include unistd.h int main(int argc, char **argv) { int fd[2] {0}; int ret pipe(fd); if (-1 ret) { perror(pipe error
); return 1; } pid_t pid fork(); if (pid 0) { close(fd[0]); int src_fd open(/home/linux/1.png, O_RDONLY); if (-1 src_fd) { perror(open src); return 1; } while (1) { char buf[1024] {0}; int rd_ret read(src_fd, buf, sizeof(buf)); if(rd_ret0) { break; } write(fd[1], buf, rd_ret); } close(fd[1]); close(src_fd); } else if (0 pid) { close(fd[1]); int dst_fd open(2.png,O_WRONLY|O_CREAT|O_TRUNC,0666); if (-1 dst_fd) { perror(open dst); return 1; } while(1) { char buf[1024]{0}; int rd_ret read(fd[0],buf,sizeof(buf)); if(rd_ret0) { break; } write(dst_fd,buf,rd_ret); } close(fd[0]); close(dst_fd); } else { perror(fork); return 1; } return 0; }父進(jìn)程讀取文件內(nèi)容通過(guò)管道傳遞給子進(jìn)程。子進(jìn)程從管道讀取數(shù)據(jù)并寫(xiě)入目標(biāo)文件。二、命名管道FIFO1. 基本概念FIFO 是一種命名管道存在于文件系統(tǒng)中。可用于無(wú)親緣關(guān)系的進(jìn)程間通信。使用mkfifo創(chuàng)建 FIFO 文件。2. 創(chuàng)建 FIFOmkfifo(myfifo, 0666);3. 讀寫(xiě)阻塞特性讀端先打開(kāi)會(huì)阻塞直到寫(xiě)端打開(kāi)。寫(xiě)端先打開(kāi)會(huì)阻塞直到讀端打開(kāi)。示例代碼寫(xiě)端程序#include fcntl.h #include stdio.h #include stdlib.h #include string.h #include sys/stat.h #include sys/types.h #include unistd.h #include errno.h int main(int argc, char **argv) { int ret mkfifo(myfifo, 0666); if (-1 ret) { // 如果是文件已存在的錯(cuò)誤程序就繼續(xù)運(yùn)行 if (EEXIST errno) { } else //如果是其他的錯(cuò)誤進(jìn)程結(jié)束 { perror(mkfifo); return 1; } } // open 會(huì)阻塞 //寫(xiě)段先運(yùn)行 寫(xiě)段會(huì)等讀段出現(xiàn) // 讀段先運(yùn)行 讀段會(huì)等寫(xiě)段出現(xiàn) int fd open(myfifo, O_WRONLY); if (-1 fd) { perror(open); return 1; } char buf[] hello,friend...
; write(fd, buf, strlen(buf) 1); close(fd); return 0; }讀端程序#include errno.h #include fcntl.h #include stdio.h #include stdlib.h #include string.h #include sys/stat.h #include sys/types.h #include unistd.h int main(int argc, char **argv) { int ret mkfifo(myfifo, 0666); if (-1 ret) { // 如果是文件已存在的錯(cuò)誤程序就繼續(xù)運(yùn)行 if (EEXIST errno) { } else //如果是其他的錯(cuò)誤進(jìn)程結(jié)束 { perror(mkfifo); return 1; } } // open 會(huì)阻塞 //寫(xiě)段先運(yùn)行 寫(xiě)段會(huì)等讀段出現(xiàn) // 讀段先運(yùn)行 讀段會(huì)等寫(xiě)段出現(xiàn) int fd open(myfifo, O_RDONLY); if (-1 fd) { perror(open); return 1; } char buf[1024] {0}; read(fd, buf, sizeof(buf)); printf(fifo_w:%s
, buf); close(fd); // remove(myfifo); return 0; }4. 錯(cuò)誤處理如果 FIFO 已存在mkfifo會(huì)失敗errno為EEXIST通常忽略該錯(cuò)誤。三、文件描述符與 FILE* 轉(zhuǎn)換1.fileno從 FILE* 獲取文件描述符FILE *fp fopen(/etc/passwd, r); int fd fileno(fp);示例代碼#include stdio.h #include unistd.h #include fcntl.h int main(int argc, char **argv) { FILE* fp fopen(/etc/passwd,r); if(NULL fp) { perror(fopen); return 1; } //fgets/fputs // FILE* - int int fd fileno(fp); char buf[100]{0}; read(fd,buf,sizeof(buf)-1); printf(%s,buf); fclose(fp); return 0; }使用fopen打開(kāi)文件得到FILE*。使用fileno獲取對(duì)應(yīng)的文件描述符用于read等系統(tǒng)調(diào)用。2.fdopen從文件描述符獲取 FILE*int fd open(/etc/passwd, O_RDONLY); FILE *fp fdopen(fd, r);示例代碼#include stdio.h #include unistd.h #include fcntl.h int main(int argc, char **argv) { int fd open(/etc/passwd,O_RDONLY); if(-1 fd) { perror(open); return 1; } //read /write char buf[100]{0}; FILE* fp fdopen(fd,r) ; if(NULL fp) { perror(fdopen); return 1; } fgets(buf,sizeof(buf),fp); printf(buf :%s,buf); fclose(fp); return 0; }使用open打開(kāi)文件得到文件描述符。使用fdopen轉(zhuǎn)換為FILE*用于fgets等標(biāo)準(zhǔn) I/O 函數(shù)。四、總結(jié)通信方式特點(diǎn)適用場(chǎng)景無(wú)名管道半雙工、親緣進(jìn)程、內(nèi)存緩沖區(qū)父子進(jìn)程間通信命名管道有名字、文件系統(tǒng)可見(jiàn)無(wú)親緣關(guān)系進(jìn)程間通信文件描述符系統(tǒng)調(diào)用、低級(jí) I/O直接操作文件或設(shè)備FILE*標(biāo)準(zhǔn) I/O、帶緩沖區(qū)高級(jí)文本或流式操作注意事項(xiàng)管道通信時(shí)及時(shí)關(guān)閉不需要的文件描述符。注意處理 SIGPIPE 信號(hào)避免進(jìn)程意外終止。FIFO 使用時(shí)注意讀寫(xiě)端的阻塞與同步。文件描述符與 FILE* 可以相互轉(zhuǎn)換便于混合使用系統(tǒng)調(diào)用和標(biāo)準(zhǔn) I/O。