用C语言编写程序建立一个pipe
c语言有名管道fifo管道的用法

c语言有名管道fifo管道的用法【C语言有名管道(FIFO管道)的用法】中括号为主题的文章【引言】C语言是一种广泛应用于系统软件开发的编程语言,拥有丰富的库函数和系统调用接口。
在C语言中,有名管道(也称为FIFO管道)是一种特殊的文件类型,用于实现不同进程之间的通信。
本文将一步一步详细介绍C语言有名管道(FIFO 管道)的用法,以帮助读者更好地理解和使用该功能。
【目录】一、什么是有名管道二、有名管道的创建三、有名管道的打开和关闭四、有名管道的读写操作五、有名管道的进程间通信六、有名管道的应用示例七、有名管道的优缺点八、总结【一、什么是有名管道】有名管道是一种特殊的文件类型,在文件系统中以文件的形式存在。
它是C语言用于进程间通信的一种方式,可以实现不同进程之间的数据传输。
有名管道是一种半双工的通信机制,允许一个进程写入数据到管道,同时另一个进程从管道中读取数据。
有名管道适用于在不相关的进程之间进行通信,特别是父子进程之间。
【二、有名管道的创建】要创建一个有名管道,首先需要使用C语言库函数mkfifo来创建一个文件节点(相当于管道的入口)。
mkfifo函数的原型如下:int mkfifo(const char *pathname, mode_t mode);其中,pathname代表要创建的有名管道的文件路径,mode用于设置管道的权限。
例如,以下代码会创建一个名为myfifo的有名管道:#include <sys/types.h>#include <sys/stat.h>int main() {mkfifo("myfifo", 0666);return 0;}运行该程序后,系统中将会被创建一个名为myfifo的有名管道。
【三、有名管道的打开和关闭】打开一个有名管道以进行读取和写入操作,可以使用C语言库函数open。
open 函数的原型如下:int open(const char *pathname, int flags);其中,pathname代表要打开的有名管道的文件路径,flags用于指定打开管道的方式(只读、只写、读写)。
Linux管道通信C语言编程示例

Linux管道通信C语⾔编程⽰例⼀、定义管道是单向的、先进先出的。
它将⼀个程序的输⼊和另⼀个程序的输出连接起来。
数据被⼀个进程读出后,将被从管道中删除。
分为⽆名和有名管道两种。
前者⽤于⽗进程和⼦进程间的通信,后者⽤于同⼀系统的两个进程间通信。
⼆、⽆名管道复制代码代码如下:int pipe(int fd[2]);其中,fd[0]⽤于读管道,fd[1]⽤于写管道。
若成功则返回零,否则返回-1,错误原因存于errno中。
三、有名管道:FIFO复制代码代码如下:int mkfifo(const char* pathname,mode_t mode)open时使⽤O_NONBLOCK,访问要求⽆法满⾜则⽴即出错返回。
erron是ENXIO。
例⼦:复制代码代码如下:fread.c //读⽂件</p> <p>#include<errno.h>#include<memory.h>#define FIFO "myfifo"main(){int fd;char buff[100];if(access(FIFO,F_OK) == -1){mkfifo(FIFO,0777);}fd=open(FIFO,O_RDONLY|O_NONBLOCK); //设置⾮阻塞打开,否则当没有输⼊时,会阻塞在read函数 </p> <p> int num; while(1){memset(buff,'\0',100); //如不清空最后的字符会出现乱码if((num=read(fd,buff,100))==0){printf("waiting.....\n");sleep(1);continue;}printf("read %d in fifo , it's %s",num,buff);sleep(1);}}</p> <p>fwrite.c //写⽂件</p> <p> </p> <p>#include<stdio.h>#include<fcntl.h>#include<memory.h>#define FIFO "myfifo"main(){int fd;char buff[100];memset(buff,'\0',100);scanf("%s",buff);if(access(FIFO,F_OK) == -1){mkfifo(FIFO,0777);}fd=open(FIFO,O_WRONLY);int num;num=write(fd,buff,strlen(buff));printf("%d char is written! It's %s\n",num,buff);}4、管道关闭:⽤close()关闭相应的⽂件描述符即可。
pipe()函数

pipe()函数介绍pipe()函数是Unix/Linux系统中一种IPC(Inter-process Communication,进程间通信)机制,用于创建一个管道(Pipe),实现父进程和子进程之间的数据通信。
管道被认为是进程间通信的最简单形式,通常被用于进程之间的数据传输和同步。
管道管道是一种半双工的数据通信方式,也就是说,同一时刻,它只能实现数据的单向传输,一端写入数据,另一端可以读出数据,但是不能同时读写数据。
管道被创建时,系统会在内存中分配一段缓冲区,用于存储数据的传输,它通常被称为“管道”,这样就可以实现进程之间的数据通信。
在Linux的文件系统中,管道被对应为一种特殊的文件类型,命名为“管道文件”,也可以被表示为“|”。
在UNIX环境下,管道是通过fork()和exec()系统调用创建的。
在C语言中,创建管道的函数是pipe(),该函数的原型如下:```cint pipe(int pipefd[2]);```该函数传递一个整型数组,用于存储两个文件描述符,分别表示管道的读端和写端。
在成功创建管道后,pipe()函数返回0,否则返回-1,表示创建管道失败。
管道的读端用于从管道中读取数据,写端用于将数据写入管道。
当读取端口被关闭时,表示管道的末端已经被关闭,写入到管道的数据在读取端口被读取后不再可用。
父进程和管道通信下面是一个简单的父子进程通信的例子。
父进程会从标准输入中读取数据,并将数据写入到管道中。
然后子进程从管道中读取数据,并将数据打印到标准输出中。
该例子中,父子进程之间使用管道进行数据通信。
```c#include <stdio.h>#include <unistd.h>#include <string.h>#define BUFSIZE 256/* 创建管道 */if (pipe(fd) < 0) {perror("pipe");return -1;}if (pid == 0) { // 子进程close(fd[1]); // 子进程关闭写端口int n = read(fd[0], buf, BUFSIZE);/* 读取父进程写入管道中的数据 */write(STDOUT_FILENO, buf, n);write(STDOUT_FILENO, "\n", 1);close(fd[0]);} else { // 父进程close(fd[0]); // 父进程关闭读端口/* 从标准输入中读取数据 */int n = read(STDIN_FILENO, buf, BUFSIZE); /* 将读取的数据写入管道 */write(fd[1], buf, n);close(fd[1]);}return 0;}```在该程序中,父进程使用write()函数向管道中写入数据,子进程使用read()函数从管道中读取数据。
linux c管道的用法

linux c管道的用法
Linux中的C管道是一种进程间通信机制,允许一个进程将其
输出连接到另一个进程的输入,从而实现数据的传输和共享。
C语言中可以使用管道来创建和操作管道。
以下是一些常见的C管道用法:
1. 创建管道:使用`pipe()`函数来创建管道。
该函数接受一个
整型数组作为参数,其中包含两个文件描述符。
第一个描述符用于读管道,第二个描述符用于写管道。
2. 管道通信:通过fork()函数创建进程后,可以使用管道进行
进程间通信。
一个进程将数据写入管道的写描述符,而另一个进程从管道的读描述符读取数据。
3. 关闭管道描述符:进程在使用完管道后,应该关闭不再需要的管道描述符。
使用`close()`函数来关闭文件描述符。
4. 重定向管道:通过dup2()函数将标准输入、标准输出或标准错误重定向到管道的输入或输出描述符。
5. 非阻塞管道:通过设置文件描述符的属性,可以将管道设置为非阻塞模式,从而避免在读取或写入管道时进程被阻塞。
6. 管道和多进程:可以使用多个管道在多个进程之间进行通信。
一个进程使用一个管道的读端和另一个进程的写端进行通信,并使用另一个管道的读端和第三个进程的写端进行通信,以此
类推。
这些是一些基本的C管道用法,还有其他更高级的用法,如
使用select()函数进行多路复用、使用匿名管道和命名管道等。
在使用C管道时,需要注意正确地打开、读取和关闭管道描
述符,并处理可能的错误。
c语言管道的用法

第二章管道一、什么是管道UNIX系统在OS的发展上,最重要的贡献之一便是该系统首创了管道(pipe)。
这也是UNIX系统的一大特色。
所谓管道,是指能够连接一个写进程和一个读进程的、并允许它们以生产者—消费者方式进行通信的一个共享文件,又称为pipe文件。
由写进程从管道的写入端(句柄1)将数据写入管道,而读进程则从管道的读出端(句柄0)读出数据。
句柄fd[0]句柄fd[1]读出端写入端二、管道的类型:1.有名管道一个可以在文件系统中长期存在的、具有路径名的文件。
用系统调用mknod( )建立。
它克服无名管道使用上的局限性,可让更多的进程也能利用管道进行通信。
因而其它进程可以知道它的存在,并能利用路径名来访问该文件。
对有名管道的访问方式与访问其他文件一样,需先用open( )打开。
2.无名管道一个临时文件。
利用pipe( )建立起来的无名文件(无路径名)。
只用该系统调用所返回的文件描述符来标识该文件,故只有调用pipe( )的进程及其子孙进程才能识别此文件描述符,才能利用该文件(管道)进行通信。
当这些进程不再使用此管道时,核心收回其索引结点。
二种管道的读写方式是相同的,本文只讲无名管道。
3.pipe文件的建立分配磁盘和内存索引结点、为读进程分配文件表项、为写进程分配文件表项、分配用户文件描述符。
4.读/写进程互斥内核为地址设置一个读指针和一个写指针,按先进先出顺序读、写。
为使读、写进程互斥地访问pipe文件,需使各进程互斥地访问pipe文件索引结点中的直接地址项。
因此,每次进程在访问pipe文件前,都需检查该索引文件是否已被上锁。
若是,进程便睡眠等待,否则,将其上锁,进行读/写。
操作结束后解锁,并唤醒因该索引结点上锁而睡眠的进程。
三、所涉及的系统调用1.pipe( )建立一无名管道。
系统调用格式 pipe(filedes)参数定义int pipe(filedes);int filedes[2];其中,filedes[1]是写入端,filedes[0]是读出端。
管道的一些实例代码

int main( )
{
int pfds[ 2 ];
if( pipe( pfds )==0 )
{
if( fork( )==0 )
{
close( 1 );
dup2( pfds[ 1 ],1 );
close( pfds[ 0 ] );
execlp( "ls","ls","-l",NULL );
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char* pathname,mode_t mode );创建一个命名管道
记住:管道只不过是一对文件描述符因此所有能够操作文件描述符的函数都可用于管道。这些函数
包括但不限于select,read,write,fcntl,freopen。
/*
myPipe[ 1 ]向管道写入数据;myPipe[ 0 ]从管道读取数据。
*/
int main( )
{
const char* string={"A simple message."};
int ret,myPipe[ 2 ];
char buffer[ MAX_LINE+1 ];
//create the pipe
}
else
{
close( 0 );
dup2( pfds[ 0 ],0 );
close( pfds[ 1 ] );
execlp( "wc","wc","-l",NULL );
c语言pipe函数,pipe函数(C语言)
c语⾔pipe函数,pipe函数(C语⾔)pipe我们⽤中⽂叫做管道。
以下讲解均是基于Linux为环境:函数简介所需头⽂件#include函数原型int pipe(int fd[2])函数传⼊值fd[2]:管道的两个⽂件描述符,之后就是可以直接操作者两个⽂件描述符返回值 成功0 失败-1什么是管道管道是Linux ⽀持的最初Unix IPC形式之⼀,具有以下特点:管道是半双⼯的,数据只能向⼀个⽅向流动;需要双⽅通信时,需要建⽴起两个管道; 只能⽤于⽗⼦进程或者兄弟进程之间(具有亲缘关系的进程); 单独构成⼀种独⽴的⽂件系统:管道对于管道两端的进程⽽⾔,就是⼀个⽂件,但它不是普通的⽂件,它不属于某种⽂件系统,⽽是⾃⽴门户,单独构成⼀种⽂件系 统,并且只存在与内存中。
数据的读出和写⼊:⼀个进程向管道中写的内容被管道另⼀端的进程读出。
写⼊的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。
管道的创建#includeint pipe(int fd[2])该函数创建的管道的两端处于⼀个进程中间,在实际应⽤中没有太⼤意义,因此,⼀个进程在由pipe()创建管道后,⼀般再fork⼀个⼦进程,然后通过管道实现⽗⼦进程间的通信(因此也不难推出,只要两个进程中存在亲缘关系,这⾥的亲缘关系指 的是具有共同的祖先,都可以采⽤管道⽅式来进⾏通信)。
管道的读写规则管道两端可 分别⽤描述字fd[0]以及fd[1]来描述,需要注意的是,管道的两端是固定了任务的。
即⼀端只能⽤于读,由描述字fd[0]表⽰,称其为管道读端;另 ⼀端则只能⽤于写,由描述字fd[1]来表⽰,称其为管道写端。
如果试图从管道写端读取数据,或者向管道读端写⼊数据都将导致错误发⽣。
⼀般⽂件的I/O 函数都可以⽤于管道,如close、read、write等等。
从管道中读取数据:如果管道的写端不存在,则认为已经读到了数据的末尾,读函数返回的读出字节数为0; 当管道的写端存在时,如果请求的字节数⽬⼤于PIPE_BUF,则返回管道中现有的数据字节数,如果请求的字节数⽬不⼤于PIPE_BUF,则返回管道中 现有数据字节数(此时,管道中数据量⼩于请求的数据量);或者返回请求的字节数(此时,管道中数据量不⼩于请求的数据量)。
c++ 管道 文件读写方法
在C++ 中,可以使用管道(pipe)来实现进程间的通信,以及使用文件读写方法来读写文件。
下面分别介绍这两种方法。
一、管道(pipe)管道是一种进程间通信的方式,它允许父进程和子进程之间进行数据传输。
在C++ 中,可以使用`pipe()` 函数创建管道,并使用`read()` 和`write()` 函数进行读写操作。
下面是一个简单的示例代码,展示如何使用管道实现父子进程之间的数据传输:```c++#include <unistd.h>#include <fcntl.h>#include <iostream>int main() {int fd[2];pipe(fd); // 创建管道pid_t pid = fork(); // 创建子进程if (pid == 0) { // 子进程close(fd[0]); // 关闭管道的读端char buffer[1024];ssize_t n = read(fd[1], buffer, sizeof(buffer)); // 从管道中读取数据std::cout << "Received data: " << buffer << std::endl;exit(0);} else { // 父进程close(fd[1]); // 关闭管道的写端write(fd[0], "Hello, world!", 13); // 向管道中写入数据}return 0;}```在上面的代码中,我们首先使用`pipe()` 函数创建了一个管道,并获取了管道的文件描述符数组`fd`。
然后,我们使用`fork()` 函数创建了一个子进程,并在子进程中关闭了管道的读端,从管道中读取数据。
在父进程中,我们关闭了管道的写端,向管道中写入数据。
二、文件读写方法在C++ 中,可以使用标准库中的文件读写函数来实现文件的读写操作。
用C语言编写程序建立一个pipe
1、用C语言编写程序,建立一个pipe, 同时父进程生成一个子进程,子进程向pipe写入一个字符串”Hello.”,父进程从pipe中读取该字符串。
5'#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <unistd.h>#include <sys/wait.h>int main(){char buf[20];int piledes[2];pid_t pid;int ret;if(ret = pipe(piledes) == -1){perror("error on pipe:");exit(-1);}else{pid = fork();if(pid < 0){perror("error on fork:");exit(-1);}else if(pid == 0){close(piledes[0]);printf("to fu:");fgets(buf,sizeof(buf)-1,stdin);if((ret = write(piledes[1],buf,strlen(buf))) < 0){perror("error on writing:");exit(-1);}close(piledes[1]);}else{close(piledes[1]);if((ret = read(piledes[0],buf,sizeof(buf)-1)) < 0){perror("error on reading:");exit(-1);}buf[ret] = '\0';printf("from zi:%s\n",buf);close(piledes[0]);}}return 0;}2、编写一个 C语言程序lswc,使之功能能和ls | wc 等价。
c语言中handle的用法
c语言中handle的用法在 C 语言中,handle 是一种用于管理进程间通信的机制。
它可以用于实现进程间的同步和互斥,以及进程间的数据交换。
下面是handle 的一些用法:1. 创建 handle:使用 create_handle_map 函数可以创建handle。
该函数返回一个指向 handle_map 结构的指针,该结构包含了 handle 的信息。
2. 访问 handle:使用 map_handle 函数可以访问 handle。
该函数将一个进程的 handle 映射到另一个进程的地址空间中,从而使两个进程可以访问同一个数据结构。
3. 创建进程间通信的管道:使用 create_pipe 函数可以创建进程间通信的管道。
该函数返回一个指向 pipe_info 结构的指针,该结构包含了管道的信息。
4. 打开文件:使用 open 函数可以打开文件。
该函数返回一个指向文件描述符的指针。
可以使用 get_file_descriptor 函数获取文件描述符的 handle。
5. 使用 handle 进行进程间通信:使用 spawn 函数可以创建新进程,并在该进程中使用 create_handle_map 函数创建 handle。
然后,可以使用 map_handle 函数将 handle 映射到其他进程的地址空间中,从而实现进程间通信。
6. 销毁 handle:使用 destroy_handle_map 函数可以销毁handle。
该函数删除 handle_map 结构,并释放分配给 handle 的所有内存资源。
handle 是 C 语言中用于进程间通信的一种重要机制,它可以实现进程间的同步和互斥,以及进程间的数据交换。
使用 handle 可以提高程序的可移植性和可扩展性,使程序更加灵活和高效。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1、用C语言编写程序,建立一个pipe, 同时父进程生成一个子进程,子进程向pipe写入一个字符串”Hello.”,父进程从pipe中读取该字符串。
5'#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <unistd.h>#include <sys/wait.h>int main(){char buf[20];int piledes[2];pid_t pid;int ret;if(ret = pipe(piledes) == -1){perror("error on pipe:");exit(-1);}else{pid = fork();if(pid < 0){perror("error on fork:");exit(-1);}else if(pid == 0){close(piledes[0]);printf("to fu:");fgets(buf,sizeof(buf)-1,stdin);if((ret = write(piledes[1],buf,strlen(buf))) < 0){perror("error on writing:");exit(-1);}close(piledes[1]);}else{close(piledes[1]);if((ret = read(piledes[0],buf,sizeof(buf)-1)) < 0){perror("error on reading:");exit(-1);}buf[ret] = '\0';printf("from zi:%s\n",buf);close(piledes[0]);}}return 0;}2、编写一个 C语言程序lswc,使之功能能和ls | wc 等价。
(也就是利用,fork,exec,以及ls,wc,以及重定向,或者是管道的系统调用) 13’#include <stdio.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <string.h>#include <unistd.h>#include <stdlib.h>#include <sys/wait.h>#include <sys/stat.h>#include <errno.h>#include <fcntl.h>#include <string.h>int main(int argc,char *argv[]){int pildes[2];int ret;char *argument[3];pid_t pid;char buf[1000];if(argc < 2){printf("que shao can shu\n");exit(0);}argument[0] = "ls";argument[1] = "/";argument[2] = NULL;if((ret = pipe(pildes)) < 0){perror("error on pipe:");exit(-1);}pid = fork();if(pid <0){printf("fork error\n");exit(-1);}if(pid == 0){close(pildes[0]);dup2(pildes[1],1);execvp("ls",argument);close(pildes[1]);}else{close(pildes[1]);// dup2(fildes[0],0);if(strcmp((argv[1]),"wc") == 0){bzero(buf,sizeof(buf));if((ret = read(pildes[0],buf,sizeof(buf))) < 0){printf("error on reading:");exit(-1);}buf[ret] = '\0';printf("%s",buf);close(pildes[0]);}}return 0;}3、实现一个具有头节点的链表。
要求具有create, insert, delete, search功能,能对链表。
编写一个应用程序,使用上面的函数。
10'#include <stdio.h>#include <string.h>#include <stdlib.h>#include <error.h>#define PASSWD 111111struct student{int num;char name[20];float grade;struct student *next;};typedef struct student stuNode;typedef struct student *stuPtr;int stuwrite(stuPtr head){FILE *fp;fp = fopen("stu","w");while(head->next != NULL){head = head->next;fwrite(head,sizeof(stuNode),1,fp);}close(fp);return 0;}stuPtr sturead(){FILE *fp;stuPtr head,p1,p2;int a;head = (stuPtr)malloc(sizeof(stuNode));head->next = NULL;p1 = head;fp = fopen("stu","r");do{p2 = (stuPtr)malloc(sizeof(stuNode));p2->next = NULL;a = fread(head,sizeof(stuNode),1,fp);p1->next = p2;p1 = p2;}while(a == 1);fclose(fp);return head;}void creat(){stuPtr head,p;head = (stuPtr)malloc(sizeof(stuNode));p = (stuPtr)malloc(sizeof(stuNode));p->next = NULL;head->next = p;printf("学号:");scanf("%d",&(p->num));getchar();printf("姓名:");scanf("%s",p->name);getchar();printf("成绩:");scanf("%f",&(p->grade));getchar();stuwrite(head);}stuPtr insert(stuPtr head){stuPtr p,q;p = (stuPtr)malloc(sizeof(stuNode));printf("学号:");scanf("%d",&(p->num));getchar();printf("姓名:");scanf("%s",p->name);getchar();printf("成绩:");scanf("%f",&(p->grade));getchar();q = head;while(q->next != NULL && p->num > q->next->num) {q = q->next;}p->next = q->next;q->next = p;stuwrite(head);p = sturead();return p;}stuPtr search(stuPtr head,int num){stuPtr p1,p2;int flag;p1 = (stuPtr)malloc(sizeof(stuNode));p2 = (stuPtr)malloc(sizeof(stuNode));p1 = head;while(p1->next != NULL){flag = 0;p2 = p1;p1 = p1->next;if(p1->num == num){flag = 1;break;}}if(flag == 1){p1 = p2;return p1;}else{printf("没有此人\n");return NULL;}}stuPtr delete(stuPtr head, int num) {stuPtr p1,p2;int flag;p1 = search(head,num);p2 = p1->next;p1->next = p2->next;free(p2);stuwrite(head);p1 = sturead();return p1;}void print(stuPtr head){stuPtr p;int i;printf("学号\t姓名\t成绩\n");p = head->next;while(p != NULL){if(p->num >0 && p->grade >0){printf("%d\t%s\t%.1f\n",p->num,p->name,p->grade);}p = p->next;}}void print1(stuPtr p){printf("学号\t姓名\t成绩\n");while(p != NULL){if(p->num >0 && p->grade >0){printf("%d\t%s\t%.1f\n",p->num,p->name,p->grade);}p = p->next;}}int main(){int choose,num;stuPtr head,p;head = (stuPtr)malloc(sizeof(stuNode));p = (stuPtr)malloc(sizeof(stuNode));while(1){printf("1\t创建链表\n2\t添加节点\n3\t删除节点\n4\t查找学生\n5\t查看所有学生信息\n0\t退出\n");scanf("%d",&choose);switch(choose){case 1:creat();break;case 2:head = sturead();insert(head);break;case 3:head = sturead();printf("删除学生的学号:");scanf("%d",&num);delete(head,num);break;case 4:head = sturead();printf("学生学号:");scanf("%d",&num);p = search(head,num);p = p->next;print1(p);break;case 5:head = sturead();print(head);case 0:break;default:break;}}return 0;}。