C语言进程间通信(二)——命名管道

 

FIFO也称命名管道,是一种文件类型,在文件系统中可见到。管道由于没有名字,所以只能限定在亲缘关系的进程之间的通信。而通过FIFO任意进程之间都能够进行通信了。FIFO的特点如下:

 

  • 命名管道可用于任何两个进程之间的通信,比管道灵活得多
  • 命名管道作为特殊文件存在文件系统中,当进程使用结束后仍存在文件系统,需要“手动”删除
创建一个命名管道可以用mkfifo [管道名],删除可以用unlink [管道名实现]。当然用C程序创建一个管道文件也是很方便的。
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>

int main(int argc, char **argv)
{
        mode_t mode = 0666;
        if (argc != 2) {
                printf("Usage: ./mkfifo.out [NAME]\n");
                exit(-1);
        }
        if ((mkfifo(argv[1], mode)) < 0) {
                printf("mkfifo error\n");
                exit(-1);
        }
        printf("created");
        return 0;
}
 写命名管道代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<sys/types.h>
#include<limits.h>
#include<string.h>

#define BUFS PIPE_BUF

void err_quit(char *msg) {
        printf("%s\n",msg);
        exit(-1);
}

int main(){
        int fd;
        if ((fd = open("fifo",O_WRONLY)) < 0) {
                err_quit("open error");
        }
        char buf[BUFS] = "Hello world";
        write(fd,buf,strlen(buf));
        return 0;
}
 发送消息方式如下
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<sys/types.h>
#include<limits.h>
#include<string.h>

#define BUFS PIPE_BUF

void err_quit(char *msg) {
        printf("%s\n",msg);
        exit(-1);
}

int main(){
        int fd;
        if ((fd = open("fifo",O_RDONLY)) < 0) {
                err_quit("open error");
        }
        char buf[BUFS];
        int len = read(fd,buf,BUFS);
        if (len < 0) {
                err_quit("read error");
        }
        printf("Get: %s\n",buf);
        return 0;
}
 上面的代码都很浅显易懂的,如果有进程读打开FIFO,且FIFO内没有数据,则对设置了阻塞标志的读操作来说,将一直阻塞,如果没有设置阻塞标志,则读操作会返回-1,errno的值是EAGAIN。尽管当前FIFO中有数据,只要别的进程读操作在进行时,本进程也会阻塞。
对于设置了阻塞标志的写操作,当要写入的数据量不大于PIPE_BUF时,将保证写入的原子性,当没有进程在读FIFO,那么设置了阻塞标志的写进程也会阻塞。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Dart 中可以使用命名管道来进行进程间通信。以下是一个 Windows 系统中使用 Dart 进行进程间通信示例代码: ```dart import 'dart:io'; void main() async { // 创建一个命名管道 var server = await ServerSocket.bind('127.0.0.1', 0); var pipe = await server.asyncExpand((client) => client).pipe(); // 启动一个子进程 var process = await Process.start('dart', ['client.dart'], stdin: pipe.sink, stdout: pipe.sink); // 从管道中读取数据 await pipe.stream.listen((data) { print('Received: ${new String.fromCharCodes(data)}'); }); // 等待子进程结束 await process.exitCode; } ``` 上述代码创建了一个命名管道,通过这个管道来启动一个子进程,并通过管道来进行通信。 需要注意的是,上面的示例代码需要配合一个名为 "client.dart" 的客户端代码使用。 ### 回答2: Dart是一种基于面向对象和C语言风格的编程语言,由谷歌开发并广泛应用于前端和移动应用开发领域。Dart语言提供了丰富的库和工具来支持各种操作系统和平台,包括Windows。 在Windows平台上,Dart提供了一种称为命名管道(Named Pipe)的进程间通信机制。命名管道是一种特殊的文件,用于实现不同进程之间的通信。通过命名管道,进程可以在同一台计算机上进行双向通信,并且支持多个进程同时连接。 使用Dart的命名管道进行进程间通信示例代码如下: ```dart import 'dart:io'; void main() async { var pipeName = '\\\\.\\pipe\\my_named_pipe'; var server = await ServerSocket.bind(pipeName); print('Named pipe server is listening on $pipeName'); var socket = await server.first; print('Client connected'); socket.listen((List<int> data) { var message = String.fromCharCodes(data); print('Received: $message'); // Process and respond to the message var response = 'Hello, client!'; socket.add(response.codeUnits); }); // When the connection is closed await socket.done; } ``` 上述代码创建了一个命名管道服务端,监听指定的命名管道。一旦有客户端连接,服务器就会收到通知,并通过监听客户端的消息进行数据交互。在代码中的注释部分,可以向客户端发送响应消息。 接下来,让我们来看一个客户端示例: ```dart import 'dart:io'; void main() async { var pipeName = '\\\\.\\pipe\\my_named_pipe'; var socket = await Socket.connect(pipeName); var message = 'Hello, server!'; socket.add(message.codeUnits); socket.listen((List<int> data) { var response = String.fromCharCodes(data); print('Received: $response'); // Process the response from the server socket.close(); }); // When the connection is closed await socket.done; } ``` 上述代码创建了一个命名管道客户端,连接到指定的命名管道,并向服务器发送消息。在代码中的注释部分,可以处理从服务器返回的响应消息。 通过以上示例代码,我们可以看到Dart的命名管道在Windows平台上实现了真实可用的进程间通信命名管道可以用于不同Dart进程之间的通信,使得开发者能够轻松地实现数据交换和协作。 ### 回答3: Dart 是一种通用的编程语言,它可以在不同平台上运行,包括 Windows 操作系统。在 Windows 下,Dart 提供了一种进程间通信的机制,即命名管道(Named Pipe)。 命名管道是一种特殊的文件,用于在不同进程之间进行通信。在 Windows 示例中,我们可以通过 Dart 的 `dart:io` 包中的 `Process.start` 方法创建一个新的进程,并使用命名管道进行进程间通信。 首先,我们需要创建一个命名管道。可以通过调用 Windows 命令行命令 `mkfifo` 来创建一个命名管道文件,例如: ```dart Process.run('mkfifo', ['my_pipe']); ``` 然后,在 Dart 中,我们可以使用 `Process.start` 方法启动一个新的进程,并在新进程中读取或写入命名管道。例如,我们可以使用以下示例代码在一个 Dart 程序中启动另一个 Dart 程序,并通过命名管道进行进程间通信: ```dart import 'dart:io'; void main() async { final pipe = await Process.start('dart', ['child.dart'], mode: ProcessStartMode.detached); final input = pipe.stdin; final output = await pipe.stdout.transform(Utf8Decoder()).join(); // 像命名管道中写入数据 input.writeln('Hello from parent process!'); // 从命名管道中读取数据 print(output); } ``` 在上面的示例中,`dart` 命令会启动 `child.dart` 程序作为子进程,并建立一个命名管道进行通信。父进程中的 `input` 可以用于向管道中写入数据,而 `output` 则是通过管道读取的数据。 需要注意的是,命名管道是一种进程间通信的机制,所以在 Windows 示例中,我们需要在两个不同的 Dart 程序中分别处理读取和写入。在实际使用中,我们可以根据具体需求,使用命名管道进行进程间通信,并根据不同平台的特性来编写相应的代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值