windows c++程序員開始用linux編程(二)創建新進程

在windows下,創建一個進程可以用CreateProcess,它將啓動另一個程序;
而在linux下,創建一個進程可以用fork,顧名思義就是“分叉”,調用fork就像孫悟空叫一聲“變”,於是出現了兩個孫悟空,而且兩個人在當時是完全一樣的,他們共享同樣的過去,但他們通常應該有不一樣的未來,於是兩個孫悟空要立即判斷出自已是不是變出來的那一個,這就要使用調用fork後的返回值,然後就可以做符合身分的事了。那如果程序只能創建自已的複本,linux不就只能運行一個程序的多個複本嗎?還沒完呢,通過fork的返回值判斷出自已是複本,就可以立即調用某個以exec開頭的系統函數執行另一個程序,這個程序將替換自已。
表面上看起來linux下的多進程較之windows下的多進程要複雜一些,要先“分叉”(即fork)再變身(即exec*),這樣的兩步走肯定是有好處的,只fork不exec*,不就像windows下的多線程了嗎?
看看這篇文章:Linux下的多進程編程 ,你就更明白了。

fork演示程序:
#include <sys/types.h>
#include <unistd.h>
#include <iostream>

int main()
{
        int i;
        std::cout << "before fork." << "/tpid:" << getpid() << std::endl;
        if(fork() == 0) //child process
        {
                std::cout << "child process." <<  "/tpid:" << getpid() << std::endl;
        }
        else
        {
                std::cout << "main process." <<  "/tpid:" << getpid() << std::endl;
        }
        std::cout << "end fork." <<  "/tpid:" << getpid() << std::endl;
        return 0;
}

exec*函數可以將調用的進程用新進程替換,以execl爲例,做做練習:
[code]
//file: demo_execl.cpp
#include <iostream>
#include <sys/unistd.h>

int main(int argc, char* argv[])
{
 if(execl("./print_cmdline.out", "arg0", "arg1", (char*)0) < 0)
 {
  std::cout << "execl error" << std::endl;
  return -1;
 }

 return 0;
}
[/code]

[code]
//print_cmdline.cpp
#include <iostream>

int main(int argc, char* argv[])
{
 for(size_t i = 0; i < argc; ++i)
  std::cout << argv[i] << " ";
 std::cout << std::endl;
 return 0;
}
[/code]

$g++ demo_execl.cpp -o demo_execl.out
$g++ print_cmdline.cpp -o print_cmdline.out
$ ./demo_execl.out
arg0 arg1

哎呀,print_cmdline.out的argv[0]竟然不是"./print_cmdline.out",那怎麼在print_cmdline.out獲得程序自身的名稱啊,我以前一直取用argv[0]的?在linux下你應該這樣做:
[code]
//file:getAppPathName.cpp
#include <sys/types.h>
#include <sys/unistd.h>
#include <iostream>
#include <string>

std::string getAppPathName();

int main()
{
        std::cout << getAppPathName() << std::endl;
        return 0;
}

std::string getAppPathName()
{
        char buffer[2048];
        int count = readlink( "/proc/self/exe", buffer, sizeof(buffer)/sizeof(buffer[0]) );
        assert( count >= 0 && count < sizeof(buffer)/sizeof(buffer[0]) );
        buffer[count] = '/0';
        return buffer;
}
[/code]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章