Unix C学习笔记17 进程间通信,有名管道,无名管道,管道使用的特殊情况

进程间通信(IPC)

想要用无名管道,得是父子进程或同一个父进程的兄弟进程

有名管道

数据先进先出 

输出重定向到管道,输入hello,cat从管道读取hello,完成两个bash进程的通信

管道文件大小还是为0

写入,不读时管道文件大小也是0 

管道文件只有i节点,没有数据块,而ls -l查看的是数据块的大小

有名管道的本质是内核维护的一块存储区,A写入,B读走,与磁盘的数据块没有关系

但是内存地址不能告诉用户,防止内核数据泄露,所以将该块存储区与文件系统挂钩,伪造成一种特殊文件,通过文件名找到的不是磁盘的数据块,而是内存的存储区

通过ulimit -a查看该存储区大小,为512 bytes*8    4096 为一页

mkfifo函数

scanf() hello\n 把hello存入指定存储区,\n存入输入缓冲区

fgets() hello\n 把hello\n一起存入存储区

vi wfifo.c 写入数据

vi rfifo.c 读出数据

read函数为阻塞函数,write向管道文件写数据时,read会阻塞等待读取管道文件数据

write写完数据,close管道文件后,管道堵死,read读不到数据返回0,表示对方关闭管道

 运行wfifo

 运行rfifo后,wfifo显示发送数据

发送数据

 输入"!"跳出循环,父进程关闭管道

无名管道

无名管道不通过文件系统找内存地址,而是通过2个文件描述符,1个代表管道的一端

int pipe(int pipefd[2]);int pipefd[2]为输出型参数,是一个数组,存放2个文件描述符

int fd[2];

pipe(fd);

fd[0]读端,fd[1]写端

只有子进程才能继承父进程的文件描述符表,才能用到无名管道

 

 

 

 若将父进程关闭读端,子进程关闭写端放在循环之后,即通信时父子进程同时开启读写端,读写端被双重占用

仍然可以传输数据,但是问题出现在关闭时

父进程关闭读写端,子进程占用读写端,写端没关闭,子进程阻塞在read函数,父进程阻塞在回收子进程wait

主要原因是子进程自己留了写端导致子进程无法结束,父进程在哪关影响貌似不大

特殊情况

管道符号

ls -l /etc | more:分屏,ls将数据传给more

ifconfig | grep inet:从ifconfig筛选inet相关的数据

 

ifconfig | grep inet在bash下输入,ifconfig/grep为2个子进程

 bash创建两个新进程A/B,A创建无名管道

将写端描述符复制到A的1,1不再对应显示器而是对应写端,进程A所有printf输出的内容都往写端走

将读端描述符复制到B的0,0不再对应键盘而是对应读端

A变身成ifconfig,输出的内容到管道写端,B变身成gret,读的所有东西从管道读端读

将2个进程通过管道连接起来

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Dart 是 Google 开发的编程语言,可以用来开发移动应用和 web 应用。命名管道UNIX 系统中的一种 IPC(进程间通信)方式,可以在不同进程之间传递数据。在 Dart 中,可以使用 dart:io 库中的 NamedPipe 类来操作命名管道。 下面是一个简单的 Unix 示例,演示了如何在两个不同的 Dart 程序之间使用命名管道进行通信: 程序1(sender.dart) ```dart import 'dart:io'; main() async { var pipe = await NamedPipeServer.create('/tmp/my_pipe'); var sink = pipe.sink; sink.write('Hello from sender!'); await sink.flush(); await sink.close(); } ``` 程序2(receiver.dart) ```dart import 'dart:io'; main() async { var pipe = await NamedPipeClient.connect('/tmp/my_pipe'); var input = pipe.input; var message = await input.read(); print(message); await input.close(); } ``` 在这个示例中,程序 1 使用 NamedPipeServer.create() 创建了一个名为 /tmp/my_pipe 的命名管道,并向其中写入了一条消息 "Hello from sender!"。程序 2 使用 NamedPipeClient.connect() 连接到了同一个命名管道,并从中读取了消息,最后打印出来。 ### 回答2: Dart是一种跨平台的编程语言,支持在不同的操作系统上进行开发。在Unix系统中,进程间通信是一个非常重要的概念。命名管道是一种用于在不同进程之间进行通信的机制。 在Dart中,可以使用dart:io包来实现使用命名管道进行进程间通信的功能。首先,需要创建一个命名管道。可以使用File类的static方法mkfifo来创建一个命名管道文件。 具体示例代码如下: import 'dart:io'; void main() { String pipePath = './mypipe'; // 命名管道的文件路径 Process.start('mkfifo', [pipePath]).then((Process process) { print('命名管道已创建'); // 接下来可以进行进程间通信的操作 }); } 上面的示例代码中,首先使用Process.start方法调用mkfifo命令来创建一个命名管道文件,然后通过then回调函数来监听创建命名管道的结果,并在命名管道创建成功后进行进一步的处理。 在创建命名管道后,就可以使用命名管道进行进程间通信了。可以使用File类来打开命名管道,并进行读写操作。具体的进程间通信的操作可以根据需求进行自定义。 需要注意的是,使用命名管道进行进程间通信时,需要确保读、写操作的顺序正确,以避免出现阻塞的情况。此外,命名管道也可以用于进程间的同步操作,例如等待另一个进程完成某个指定的任务后再进行下一步操作。 总而言之,Dart可以通过使用dart:io包来实现在Unix系统中使用命名管道进行进程间通信的功能。通过创建命名管道文件,然后使用File类打开该文件进行读写操作,可以实现不同进程之间的通信与同步。具体的操作可以根据需求进行自定义。 ### 回答3: 在Unix系统中,进程间通信是非常重要的,为了实现进程间的数据传递,可以使用命名管道。Dart语言也提供了类似的方法来实现进程间通信。 命名管道是一种特殊的文件,它可以用来实现进程间的读写操作。在Unix示例中,首先我们需要创建一个命名管道,在Dart中可以使用File类的create方法来创建文件。创建命名管道的操作类似于创建普通文件,只是我们需要给文件一个特殊的名称,通常以“/tmp/”开头。 在创建完命名管道之后,我们可以使用File类的open方法来打开管道。在Unix示例中,我们需要使用O_RDONLY或者O_WRONLY标识符来指定管道的读写模式。然后,我们可以使用File类的read方法来读取管道中的数据,使用write方法来写入数据。 在进程间通信时,通常会有一个进程负责写入数据,另一个进程负责读取数据。这两个进程可以通过访问同一个命名管道来实现通信。读取进程会在打开管道之后一直等待数据的到来,直到写入进程向管道中写入数据。然后读取进程会读取数据并进行相应的处理。 需要注意的是,在使用命名管道时,需要保证写入和读取的进程顺序是正确的,否则可能会产生读写阻塞的问题。此外,写入和读取的进程在使用管道时需要进行同步,以免出现数据竞争的情况。 总结起来,Dart语言可以使用命名管道来实现进程间通信,类似于Unix中的示例。使用命名管道可以在进程间传递数据,实现数据的读写操作。但是需要注意保证进程的顺序和同步,以确保通信的正确性和稳定性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值