我有多个子进程由同一个父进程“ fork ”,我尝试在所有这些子进程之间构建 pipe 连接,如链表结构。 child 1 将数据发送给 child 2, child 2 给 child 3 .... child N 给 child 1。有什么合适的方法吗?
此外,如果我在进程之间创建和通信,我如何强制父进程“等待”自 wait() 或 waitpid() 以来的所有进程完成他们的工作> 等待第一个完成的过程,但我需要等待所有过程。这是另一个问题。
谢谢...
最佳答案
这本质上就是 shell 在构建重定向链时所做的事情,即类似于
ls | grep foo | sort | uniq
有一些优秀的 Unix 编程入门书籍,其中通过本书实现了一个简单的 shell。 shell 的任务之一是重定向。其中一本书是 Michael K. Johnson 和 Erik W. Troan 合着的“Linux Application Programming”。
本书主页:http://ladweb.net/
要为 N 个进程构建重定向链,您需要 N-1 个管道。对于每个重定向,您使用 pipe(int fds[2]) 系统调用创建一个管道。在 fork()ing 之后,但在 execving 之前,使用 dup2(int from, int to) 将管道的末端“连接”到标准每个进程的输入(0)或标准输出。这是一个过于简化的代码,没有错误检查:
int pipe_A[2];
int pipe_B[2];
pipe(pipe_A);
pipe(pipe_B);
pid_t pid_A, pid_B, pid_C;
if( !(pid_A = fork()) ) {
dup2(pipe_A[1], 1); /* redirect standard output to pipe_A write end */
execv(...);
}
if( !(pid_B = fork()) ) {
dup2(pipe_A[0], 0); /* redirect standard input to pipe_A read end */
dup2(pipe_B[1], 1); /* redirect standard output to pipe_B write end */
execv(...);
}
if( !(pid_C = fork()) ) {
dup2(pipe_B[0], 0); /* redirect standard input to pipe_B read end */
execv(...);
}
请注意,如果管道的数组索引用于 stdio 重定向,则它们的选择方式会反射(reflect)标准输入/输出文件描述符。这个选择不是随意的。
当然,你可以将管道连接到任何文件描述符(例如,有一些应用程序希望它们的父级打开,比如 fd 3 和 4,连接到管道)并且大多数 shell 也直接支持这一点(例如 1> &3 会将 stdout 重定向到 fd 3)。然而,pipe(int fds[2]) 的数组索引当然是 0 和 1。我之所以这么说,是因为我有一些 cargo-cult-programming 学生,他们盲目地将目标 fds 也用于管道系统调用数组。
等待所有子进程完成使用 waitpid(-1, NULL, 0) – 我认为这是我的预回答者的意思,这意味着:WAITING所有子进程结束。另一种选择是在循环中调用 wait(),这将返回刚刚终止的子进程的 pid。如果再次调用,还有一个 child 在跑,它会再次阻塞。如果没有 child ,它将返回-1;我更喜欢 waitpid 解决方案。
关于c - 是否可以在同一父进程(LINUX、POSIX)创建的两个子进程之间建立管道,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5225810/
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html
我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我构建了两个需要相互通信和发送文件的Rails应用程序。例如,一个Rails应用程序会发送请求以查看其他应用程序数据库中的表。然后另一个应用程序将呈现该表的json并将其发回。我还希望一个应用程序将存储在其公共(public)目录中的文本文件发送到另一个应用程序的公共(public)目录。我从来没有做过这样的事情,所以我什至不知道从哪里开始。任何帮助,将不胜感激。谢谢! 最佳答案 无论Rails是什么,几乎所有Web应用程序都有您的要求,大多数现代Web应用程序都需要相互通信。但是有一个小小的理解需要你坚持下去,网站不应直接访问彼此
在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',