各种进程创建方式比较总结(MacOS, Win32

各种进程创建方式比较总结(MacOS,Win32,Qt) 收藏

此文于2010-03-11被推荐到CSDN首页
如何被推荐?

write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie

讨论新闻组及文件

    由于进程创建是非常基础,很重要的工作,由此导致的恶果就是每个系统自己都喜欢封装一套,以显示自己对其有原生的,较好的支持,但是,说实话,有的时候, 那方式,实在是相当别扭,这里,我讲我了解的平台/系统下的进程创建方式统一的梳理总结一下,也顺面可以比较一下各个系统的API封装情况,窥一斑而见全 豹嘛。这里很容易加入主观因素,也没有太多客观事实可以作为唯一的评定标准,那么,完成同样的工作,代码量少点总不是太坏的事情,仅以代码量为参考之一 吧,参考之二就是大家自己的感觉了。毕竟其中一些地方无法做到公平,因为所有代码并不是以精简代码为首要目的,首要目的是适应对应接口的风格.


方 式说明

    1,最简单的创建一个带参数的进程,以显示当前目录下的文件a,文件b的内容为例。
    2,展示进程的输出重定向使用,以将当前目录下的文件a,文件b定向到文件c中为例。
    3,展示进程间的管道通信技术,以将当前目录下的文件a,文件b通过管道传递给另外一个输出的进程,并且显示。
    (以下简称Test1,2,3)。

1.Shell/DOS

1.从最简单的开始吧,Shell/DOS,这种简单的情 况,Windows的DOS与Unix/Linux的Bash Shell下都差不多,以Bash为例了。(其实Windows下仅仅将cat换成type命令即可。。。。其实还是有些细微差别的,参看《从Unix的 echo与Dos的type之间的区别,看操作系统之间的软件设计哲学的不同》一文)以下因为type,dos命令的限制导致Windows下某些时候 Test3无法完成,忽略之)

jtianling$ echo "I'm File A." > a
jtianling$ echo "I'm File B." > b
jtianling$ ls
a    b
jtianling$ cat a
I'm File A.
jtianling$ cat b
I'm File B.
jtianling$ cat a b
I'm File A.
I'm File B.
jtianling$
好了,cat a b,这样简单的调用,进程创建完成,参数输入完成,显示正常。


2.输出重定向,对于Shell来说实在是小 case,那简直可以说是其原生的。

TianLings-MacBook:test jtianling$ cat a b > c
jtianling$ cat c
I'm File A.
I'm File B.
jtianling$
cat a b > c一句而已。


3.管道,还是Shell饭碗里面的内容。

jtianling$ cat a b | cat
I'm File A.
I'm File B.
cat a b | cat还是一句代码而已。


自 此,Shell完成了全部任务,可以看到Shell这玩意儿不愧是为管理,调用进程而生的家伙,完成类似任务,那是信手拈来,毫不费劲,即便是最复杂的 Test3,也没有超过一行,字符数(以下都不计空格)甚至没有达到两位数。当然,到了这里,离谱的简单,有人可能会说这种比较根本不应该加入 Shell,甚至会觉得Shell参与此分类比较简直就是作弊。。。。。bash/bat也算是一种编程语言,而且为了进程调用的方便,牺牲了那么多,为 啥不算呢?^^

2.C Runtime Library

这里运行环境是MacOS,Windows下还是得用 type....利用了C Runtime Library的system函数。
Test1:
#include <stdlib.h>

int  main() {
        system("cat a b" );
        return  0 ;
}


结果:
Running…
I'm File A.
I'm File B.

Debugger stopped.
Program exited with status value:0.

OK,
依 次类推,接下来的也就就是按照Shell的调用方式换system的参数而已了,不重复描述了,简单计算,起码都是5行内解决问题。(自然分行,没有特别 去缩减,也没有特别去增加,空行不算)有人又会说,这样使用完全是依靠了SHELL的强大,system函数不过是个简单的Shell调用而已。。。。根 本不算数,C语言本身压根就不带进程创建功能-_-!但是。。。。任务完成了吧。。。Shell本身都算,依赖于Shell完成任务,只要任务能够很好的 完成,为啥不算呢?

3.Python中的System

Python的OS模块中也有System这个C Runtime Library的函数,于是,第2种方法的好处其可以占尽,并且,因为Python作为脚本语言,少了很多负担,所以其实从完成任务的角度来说,要比C语 言更加简单一些。当然,我不知道这不属于Python社区接受的方式,也即,不知道这算不算Pythonic。
>>> import os
>>> os.system("cat a b")
I'm File A.
I'm File B.
0
当然,能够如此简单,还是少不了Shell的功劳。

4.Win32 API WinExec/ShellExcute

这两个接口都好像不怎么推荐使用了,但是使用的简单性上还算是一个量级的.放 在一起了.
Test1:

#include <windows.h>

int  _tmain(int  argc,_TCHAR* argv[])
{
    WinExec("cmd /c type a b",SW_SHOW);

    getchar();
    return  0 ;
}

Test2与Test1类似,不累述了,Test3因为type不支持管道输入,所以无法完成.


5.Win32 API CreateProcess

CreateProcess其实是平时我在Windows下创建新进程使用最 多的函数,因为可以获得新进 程的句柄,可以进行很多额外的操作,比如让新进程先停止,甚至可以hack新进程,通过API直接对新进程的内存进行write操作.....呵呵,当时 研究反外挂时的一些操作,平时用的其实也少.当时Wait相关API,只有获得CreateProcess返回的进程Handle才能进行.其实对与此 API我以前特别有一文讲述了一些经验(其实是做一个笔记,防止忘记)< Windows下 的进程创建API--CreateProcess使用经验漫谈 >

#include <windows.h>
#include <stdio.h>
#include <tchar.h>

int  _tmain( VOID ) {
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    LPTSTR szCmdline=_tcsdup(TEXT("cmd /c type a b" ));

    ZeroMemory( &si,sizeof (si) );
    si.cb = sizeof (si);
    ZeroMemory( &pi,sizeof (pi) );

    // Start the child process.
    if ( !CreateProcess( NULL,  szCmdline,NULL,FALSE,0 ,&si,&pi )) {
       printf( "CreateProcess failed ( %d ). /n ",GetLastError() );
       return  0 ;
    }
    // Wait until child process exits.
    WaitForSingleObject( pi.hProcess,INFINITE );

    // Close process and thread handles.
    CloseHandle( pi.hProcess );
    CloseHandle( pi.hThread );

    return  0 ;
}


纯C语言的接口,第一次看到此接口的时候简直懵了,后来用ShellExecute替代了,用到再后 来,CreateProcess用多了,每次copy示例代码,竟然也慢慢觉得看的顺眼了,习惯的力量是强大的..........


6.MacOS Cocoa

下面看重头戏…………
Test1:

#import <Foundation/Foundation.h>

int  main (int  argc,const  char  * argv[]) {
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
        
        NSTask *task = [[NSTask alloc] init];
        [task setLaunchPath:@"/bin/cat" ];
        
        NSMutableArray *args = [NSMutableArray array];
        [args addObject:@"a" ];
        [args addObject:@"b" ];
        // can be replace by -- NSArray *args = [NSArray arrayWithObjects:@"a",@"b",nil];
        [task setArguments:args];      
        [task launch];
        [task waitUntilExit];
        
        [task release];
        [pool drain];
        return  0 ;
}


一共15行,Cocoa中对进程进行了封装, 用NSTask来表示,并且将参数分割成一个一个字符串对象,组合起来成为一个Array后才能设定为参数,再然后,通过launch启动进程,通过 waitUntilExit等待进程推出,再释放自己分配的NSTask对象,对了,Objective C程序中,为了适应没有垃圾收集的情况,还得好好的设定自动释放内存池。

Test2:
想投机取巧一下吧,利用Shell,如下:

        NSMutableArray *args = [NSMutableArray array];
        [args addObject:@"a" ];
        [args addObject:@"b" ];
        [args addObject:@">" ];
        [args addObject:@"c" ];


你 会得到如下错误信息:
I'm File A.
I'm File B.
cat: >: No such file or directory
cat: c: No such file or directory

Debugger stopped.
Program exited with status value:0.
这是行不通的。。。。Apple给了你封装,你就得用,抵抗只有死路一条。。。。。
正 确用法:(不知道还有没有更简单的,这个方法还是自己想到的。。。。试了试还真可以用。。。。)

#import <Foundation/Foundation.h>

int  main (int  argc,const  char  * argv[]) {
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
        
        NSTask *task = [[NSTask alloc] init];
        [task setLaunchPath:@"/bin/cat" ];
        
        NSMutableArray *args = [NSMutableArray array];
        [args addObject:@"a" ];
        [args addObject:@"b" ];
        [task setArguments:args];

        NSFileManager *fm = [NSFileManager defaultManager];
        if  ([fm createFileAtPath:@"c"  contents:nil  attributes:nil ] == FALSE) {
                NSLog(@"Can't Create the file named c." );
                return  1 ;
        }
        
        NSFileHandle* fh = [NSFileHandle fileHandleForWritingAtPath:@"c" ];
        [task setStandardOutput:fh];
        
        [task launch];
        [task waitUntilExit];
        [task release];
        
        [fh closeFile];
        
        [pool drain];
        return  0 ;
}

于是乎,你可以知道了,apple是崇尚学习 的。。。。。因此,你又学会了好几个类,明白了好几个概念,
NSFileManager不 能直接创建文件然后返回 NSFileHandle进行操作的设定难道是为了更好的实行类的 分工?

Test3:
经历过Test1,Test2的洗礼后,应该会明白了,为啥苹果的笔记本起码都要7千多,苹果的一个外接完整 键盘都要500多,一根破转接线都要200(见《看到苹果 的把视频转接线当金条卖,我彻底怒了。。。。。。。 》生产效率太低估计是原因之一(可是苹果很多东西不都是中国组装的吗?)。。。。-_-!为 啥与苹果粉丝的宣传的好像不大一样啊。。。。。原因我也不知道,用苹果最大的感受是Mac Book的Fx键都被笔记本的特性完全占用,苹果自己默认设定的一些快捷键都会形成冲突,XCode的调试常用键你都得用3个以上的键组合才能按 出。。。。人性化的设计极大的培养了用户手指的灵活度。(别说可以改,VS,Eclipse,Qt Creator的调试常用快捷键为啥都只用Fx键一键调用是有原因的,这个道理Ollydbg都懂,为啥苹果这么注重用户体验及GUI设计的人为啥不懂我 是不太明白。。。。。。。难道苹果的GUI设计光是指使用鼠标或者触摸屏?唉。。。。也许我还没有适应苹果的文化吧。。。。。。当大家都被苹果的文化熏陶 后,也许苹果的东西就是好吧。。。。。。(估计说这些话会被很多人骂,所以不开新文章特别说明了,省的骂声一片,仅插播在这个枯燥的技术文章当中吧。某年 某月某日我改变主意了,再回来改掉这些文字吧。)
对了,主题是,Cocoa中的管道:

#import <Foundation/Foundation.h>

int  main (int  argc,const  char  * argv[]) {
        NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
        
        NSTask *task = [[NSTask alloc] init];
        [task setLaunchPath:@"/bin/cat" ];
        
        NSMutableArray *args = [NSMutableArray array];
        [args addObject:@"a" ];
        [args addObject:@"b" ];
        [task setArguments:args];

        NSPipe *pipe = [NSPipe pipe];
        [task setStandardOutput: pipe];

        NSTask *newTask = [[NSTask alloc] init];
        [newTask setLaunchPath:@"/bin/cat" ];
        [newTask setStandardInput: pipe];

        [task launch];
        [newTask launch];
        [task waitUntilExit];
        [newTask waitUntilExit];
        [task release];
        [newTask release];
        
        [pool drain];
        return  0 ;
}
Pipe的封装还算简单,使用也还算方便吧,但是因为Task的使用,代码量实在也够多了。

7.Qt QProcess

作为几乎对C++进行语言级别改变的框架Qt,进行了与Cocoa类似的封 装,对了,其实感觉Qt对C++从语言特性的改变 上来说类似于Cocoa对于Objective C的改变,不同的是Qt没能统治C++世界。
Test1:

#include <QtCore/QCoreApplication>
#include <QtCore/QProcess>
#include <QtCore/QStringList>

int  main(int  argc,char  *argv[])
{
    QString program = "cat" ;
    QStringList arguments;
    arguments <<"a"  <<"b" ;

    QProcess *myProcess = new  QProcess();
    myProcess->start(program,arguments);
    myProcess->waitForFinished();
    QByteArray output = myProcess->readAllStandardOutput();
    printf(" %s ",(const  char *)output);

    return  0 ;
}

QProcess就是Qt封装的进程类,需要特别说明的此类使用上在Qt4与Qt3是不同的。并且,有个问题是因为 Qt现在几乎已经是纯面向GUI的界面库了,所以QProcess默认是进行命令行不输出的,这里转了个弯,先读出了输出,然后用printf输出了。

Test2:

#include <QtCore/QCoreApplication>
#include <QtCore/QProcess>
#include <QtCore/QStringList>

int  main(int  argc,char  *argv[])
{
    QString program = "cat" ;
    QStringList arguments;
    arguments <<"a"  <<"b" ;

    QProcess *myProcess = new  QProcess();
    myProcess->setStandardOutputFile("c" );
    myProcess->start(program,arguments);
    myProcess->waitForFinished();

    return  0 ;
}
但是看了示例,什么感觉?个人感觉Qt不愧是专门做API的,靠API吃饭的与靠卖硬件为生的公司就是不一样,API的设计实 在是恰到好处,简介简练,并且,最重要的是,够用!

Test3:


#include <QtCore/QCoreApplication>
#include <QtCore/QProcess>
#include <QtCore/QStringList>

int  main(int  argc,char  *argv[])
{
    QString program = "/bin/cat" ;
    QStringList arguments;
    arguments <<"a"  <<"b" ;

    QProcess *myProcess = new  QProcess();
    QProcess *outProcess = new  QProcess();
    myProcess->setStandardOutputProcess(outProcess);

    myProcess->start(program,arguments);
    outProcess->start(program);
    myProcess->waitForFinished();
    outProcess->waitForFinished();

    QByteArray output = outProcess->readAllStandardOutput();
    printf(" %s ",(const  char *)output);
    return  0 ;
}

总体上而言,Qt没有设计pipe对应的类,但是,对于一个函数可以解决的任务来说,很明显使用起来是更加简单的,像 Cocoa那样,对这么简单的概念都进行相应的封装,其实有过度设计之嫌。。。。其实NSPipe也就2,3个函数,而且,如此例所示,其实,除了一个有 用外,NSPipe多出的那么几个都是因为多了NSPipe才出现的函数。。。。。悲哀中。。。。

总表

使用方式/代码量
Test1
Test2
Test3
SHELL
单 行5字符
单行7字符
单行9字符
C Runtime Library's system
5行
5行
5行
Python's os.system
2行
2行
2行
Win32 API WinExec/ShellExecute
6行
6行
type 限制
Win32 API CreateProcess
16行
16 行
type限制
Objective C With Cocoa
15 行
23行
23行
Qt QProcess
16 行
15行
20行

别的不 说了,起码有一点可以肯定。。。。。有的时候面向/基于对象的设计,不仅实现起来不能省代码量,就连使用起来都需要更多的代码。。。。。
而且封装 这技术,使用一定要适度,太细太过并没有太大好处。有的时候一个简单的C语言函数,已经可以做的事情,为啥我们要用3,4各类来完成?



 

原创文章作者保留版 权 转载请注明原作者 并给出链接

write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


我正在用TitaniumDeveloper编写一个应用程序,它允许我使用Javascript,PHP,Ruby和Python.它为API提供了一些可能需要的标准功能,但缺少的是全局事件.现在我想将全局热键分配给我的应用程序并且几乎没有任何问题.现在我只针对MAC,但无法找到任何Python或Ruby的解决方案.我找到了Coc
我的问题是当我尝试从UIWebView中调用我的AngularJS应用程序中存在的javascript函数时,该函数无法识别.当我在典型的html结构中调用该函数时,该函数被识别为预期的.示例如下:Objective-C的:-(void)viewDidLoad{[superviewDidLoad];//CODEGOESHERE_webView.d
我想获取在我的Mac上运行的所有前台应用程序的应用程序图标.我已经使用ProcessManagerAPI迭代所有应用程序.我已经确定在processMode中设置了没有modeBackgroundOnly标志的任何进程(从GetProcessInformation()中检索)是一个“前台”应用程序,并显示在任务切换器窗口中.我只需要
我是一名PHP开发人员,我使用MVC模式和面向对象的代码.我真的想为iPhone编写应用程序,但要做到这一点我需要了解Cocoa,但要做到这一点我需要了解Objective-C2.0,但要做到这一点我需要知道C,为此我需要了解编译语言(与解释相关).我应该从哪里开始?我真的需要从简单的旧“C”开始,正
OSX中的SetTimer在Windows中是否有任何等效功能?我正在使用C.所以我正在为一些软件编写一个插件,我需要定期调用一个函数.在Windows上,我只是将函数的地址传递给SetTimer(),它将以给定的间隔调用.在OSX上有一个简单的方法吗?它应该尽可能简约.我并没有在网上找到任何不花哨的东西
我不确定引擎盖下到底发生了什么,但这是我的设置,示例代码和问题:建立:>雪豹(10.6.8)>Python2.7.2(由EPD7.1-2提供)>iPython0.11(由EPD7.1-2提供)>matplotlib(由EPD7.1-2提供)示例代码:importnumpyasnpimportpylabasplx=np.random.normal(size=(1000,))pl.plot
我正在使用FoundationFramework在Objective-C(在xCode中)编写命令行工具.我必须使用Objective-C,因为我需要取消归档以前由NSKeyedArchiver归档的对象.我的问题是,我想知道我现在是否可以在我的Linux网络服务器上使用这个编译过的应用程序.我不确定是否会出现运行时问题,或者可
使用cocoapods,我们首先了解一下rvm、gem、ruby。rvm和brew一样,但是rvm是专门管理ruby的版本控制的。rvmlistknown罗列出ruby版本rvminstall版本号   可以指定更新ruby版本而gem是包管理gemsource-l查看ruby源gemsource-rhttps://xxxxxxxx移除ruby源gemsou
我有一个包含WebView的Cocoa应用程序.由于应用程序已安装客户群,我的目标是10.4SDK.(即我不能要求Leopard.)我有两个文件:index.html和data.js.在运行时,为了响应用户输入,我通常会使用应用程序中的当前数据填充data.js文件.(data.js文件由body.html上的index.html文件用于填充
如何禁用NSMenuItem?我点击后尝试禁用NSMenuItem.操作(注销)正确处理单击.我尝试通过以下两种方式将Enabled属性更改为false:partialvoidLogout(AppKit.NSMenuItemsender){sender.Enabled=false;}和partialvoidLogout(AppKit.NSMenuItemsender){LogoutI
我在想,创建一个基本上只是一个带Web视图的界面的Cocoa应用程序是否可行?做这样的事情会有一些严重的限制吗?如果它“可行”,那是否也意味着你可以为Windows应用程序做同样的事情?解决方法:当然可以创建一个只是一个Cocoa窗口的应用程序,里面有一个Web视图.这是否可以被称为“可可应
原文链接:http://www.cnblogs.com/simonshi2012/archive/2012/10/08/2715464.htmlFrom:http://www.idev101.com/code/Cocoa/Notifications.htmlNotificationsareanincrediblyusefulwaytosendmessages(anddata)betweenobjectsthatotherwi
如果不手动编写GNUmake文件,是否存在可以理解Xcode项目的任何工具,并且可以直接针对GNUstep构建它们,从而生成Linux可执行文件,从而简化(略微)保持项目在Cocoa/Mac和GNUstep/Linux下运行所需的工作?基本上,是否有适用于Linux的xcodebuild样式应用程序?几个星期前我看了pbtomake
我正在将页面加载到WebView中.该页面有这个小测试Javascript:<scripttype="text/javascript">functiontest(parametr){$('#testspan').html(parametr);}varbdu=(function(){return{secondtest:function(parametr){$('#testspan&#039
我正在尝试使用NSAppleScript从Objective-C执行一些AppleScript…但是,我正在尝试的代码是Yosemite中用于自动化的新JavaScript.它在运行时似乎没有做任何事情,但是,正常的AppleScript工作正常.[NSAppactivateIgnoringOtherApps:YES];NSAppleScript*scriptObject=[[NSApple
链接:https://pan.baidu.com/s/14_im7AmZ2Kz3qzrqIjLlAg           vjut相关文章Python与Tkinter编程ProgrammingPython(python编程)python基础教程(第二版)深入浅出PythonPython源码剖析Python核心编程(第3版)图书信息作者:Kochan,StephenG.出
我正在实现SWTJava应用程序的OSX版本的视图,并希望在我的SWT树中使用NSOutlineView提供的“源列表”选项.我通过将此代码添加到#createHandle()方法来破解我自己的Tree.class版本来实现这一点:longNSTableViewSelectionHighlightStyleSourceList=1;longhi=OS.sel_regist
我的Cocoa应用程序需要使用easy_install在用户系统上安装Python命令行工具.理想情况下,我想将一个bash文件与我的应用程序捆绑在一起然后运行.但据我所知这是不可能的,因为软件包安装在Python的“site-packages”目录中.有没有办法创建这些文件的“包”?如果没有,我应该如何运行ea
摘要: 文章工具 收藏 投票评分 发表评论 复制链接 Swing 是设计桌面应用程序的一个功能非常强大工具包,但Swing因为曾经的不足常常遭到后人的诟病.常常听到旁人议论纷纷,”Swing 运行太慢了!”,”Swing 界面太丑嘞”,甚至就是说”Swing 简直食之无味”. 从Swing被提出到现在,已是十年光景,Swing早已不是昔日一无是处的Swing了. Chris Adamson 和我写
苹果的开发:   我对于Linux/Unix的开发也是一窍不通,只知道可以用Java.不过接触了苹果过后,确实发现,世界上确实还有那么一帮人,只用苹果,不用PC的.对于苹果的开发,我也一点都不清楚,以下是师兄们整理出来的网站. http://www.chezmark.com/osx/    共享软件精选 http://www.macosxapps.com/    分类明了,更新及时的一个重要Mac