大悟网站设计建设一个网站的技术可行性研究
2026/1/8 4:05:19 网站建设 项目流程
大悟网站设计,建设一个网站的技术可行性研究,怎么做可以直播的网站吗,微博推广运营一、管道#xff08;Pipe#xff09;1. 基本概念管道是一种半双工的通信方式#xff0c;数据只能单向流动。只能在具有亲缘关系的进程之间使用。管道本质上是一个内核缓冲区#xff0c;通过文件描述符进行读写操作。包括读端 fd[0] 和写端 fd[1]。2. 创建管道int fd[2]; pi…一、管道Pipe1. 基本概念管道是一种半双工的通信方式数据只能单向流动。只能在具有亲缘关系的进程之间使用。管道本质上是一个内核缓冲区通过文件描述符进行读写操作。包括读端fd[0]和写端fd[1]。2. 创建管道int fd[2]; pipe(fd);3. 读阻塞Read Blocking如果管道为空读操作会阻塞直到有数据写入。示例代码#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\n); return 1; } pid_t pid fork(); if(pid0) { close(fd[0]); int i 3; while(i--) { printf(father 准备数据\n); 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\n,buf); close(fd[0]); } else { perror(fork); return 1; } return 0; }子进程调用read时父进程尚未写入数据子进程阻塞等待。父进程睡眠3秒后写入数据子进程才继续执行。4. 写阻塞Write Blocking如果管道缓冲区满写操作会阻塞直到有空间写入。示例代码#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\n); return 1; } pid_t pid fork(); if(pid0) { close(fd[0]); char buf[1024]{0}; memset(buf,a,sizeof(buf)); int i 0 ; // 写阻塞 示例 for(i0;i65;i) { write(fd[1],buf,sizeof(buf)); printf(%d\n,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; }父进程循环写入数据直到管道满后续写入会阻塞。子进程不读数据导致写端持续阻塞。5. 管道破裂Broken Pipe当读端关闭写端继续写入时会触发SIGPIPE信号默认行为是终止进程。示例代码#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\n); 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(--------------\n); close(fd[1]); } else if (0 pid) { close(fd[1]); close(fd[0]); exit(1); } else { perror(fork); return 1; } return 0; }子进程关闭了读端父进程写入数据时触发管道破裂。6. 读取管道结束EOF当写端关闭读端读取完所有数据后read返回0表示管道结束。示例代码#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\n); 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\n, buf); } close(fd[0]); } else { perror(fork); return 1; } return 0; }父进程写入数据后关闭写端。子进程读取数据当read返回0时退出循环。7. 管道复制文件管道可用于父子进程间传递大量数据如文件复制。示例代码#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\n); 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; }父进程读取文件内容通过管道传递给子进程。子进程从管道读取数据并写入目标文件。二、命名管道FIFO1. 基本概念FIFO 是一种命名管道存在于文件系统中。可用于无亲缘关系的进程间通信。使用mkfifo创建 FIFO 文件。2. 创建 FIFOmkfifo(myfifo, 0666);3. 读写阻塞特性读端先打开会阻塞直到写端打开。写端先打开会阻塞直到读端打开。示例代码写端程序#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) { // 如果是文件已存在的错误程序就继续运行 if (EEXIST errno) { } else //如果是其他的错误进程结束 { perror(mkfifo); return 1; } } // open 会阻塞 //写段先运行 写段会等读段出现 // 读段先运行 读段会等写段出现 int fd open(myfifo, O_WRONLY); if (-1 fd) { perror(open); return 1; } char buf[] hello,friend...\n; 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) { // 如果是文件已存在的错误程序就继续运行 if (EEXIST errno) { } else //如果是其他的错误进程结束 { perror(mkfifo); return 1; } } // open 会阻塞 //写段先运行 写段会等读段出现 // 读段先运行 读段会等写段出现 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\n, buf); close(fd); // remove(myfifo); return 0; }4. 错误处理如果 FIFO 已存在mkfifo会失败errno为EEXIST通常忽略该错误。三、文件描述符与 FILE* 转换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打开文件得到FILE*。使用fileno获取对应的文件描述符用于read等系统调用。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打开文件得到文件描述符。使用fdopen转换为FILE*用于fgets等标准 I/O 函数。四、总结通信方式特点适用场景无名管道半双工、亲缘进程、内存缓冲区父子进程间通信命名管道有名字、文件系统可见无亲缘关系进程间通信文件描述符系统调用、低级 I/O直接操作文件或设备FILE*标准 I/O、带缓冲区高级文本或流式操作注意事项管道通信时及时关闭不需要的文件描述符。注意处理 SIGPIPE 信号避免进程意外终止。FIFO 使用时注意读写端的阻塞与同步。文件描述符与 FILE* 可以相互转换便于混合使用系统调用和标准 I/O。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询