4.1.5 应用程序员的接口(2)
问题是您不知道我所想的编码在包含4 496 388种可能的文件的什么位置出现。根据我的编码在文件中的位置,您可能会花费5分钟以上的时间才能够找到。对文件进行排序并不能够提供帮助,因为您除了编码长度和能够包含的字符之外,对编码一无所知,这样就不能够使用类似于二叉搜索的便利的技术。
然而,假如您能够使用双核CMP,那么在策略中就可以将包含超过四百万种可能的大的文件分成两个包含两百多万种可能的文件。这样,您开发了名为find_code的程序。这个程序接收一个包含编码的文件作为输入,并执行穷尽(穷举/顺序)搜索来查找编码。技巧在于您需要操作系统帮助您在搜索中使用两个内核,您将令两个内核同时各对两个文件之一进行搜索。您的想法是"三个臭皮匠,赛过诸葛亮",如果将列表一分为二,那么找到编码所需的时间也会减半。这样,您希望操作系统同时运行find_code程序的两个版本,每个版本负责查找最初文件的一半。使用posix_spawn( )调用来启动程序,如程序清单4-1所示。
程序清单4-1
- //Listing 4-1 Program (guess_it) used to launch find_code.
-
- 1 using namespace std;
- 2 #include <iostream>
- 3 #include <string>
- 4 #include <spawn.h>
- 5 #include <sys/wait.h>
- 6
- 7 int main(int argc,char *argv[],char *envp[])
- 8 {
- 9
- 10 pid_t ChildProcess;
- 11 pid_t ChildProcess2;
- 12 int RetCode1;
- 13 int RetCode2;
- 14 int Value;
- 15 RetCode1 = posix_spawn(&ChildProcess,"find_code",NULL,
- 16 NULL,argv,envp);
- 17 RetCode2 = posix_spawn(&ChildProcess2,"find_code",NULL,
- 18 NULL,argv,envp);
- 19 wait(&Value);
- 20 wait(&Value);
- 21 return(0);
- 22 }
第15行和第17行的posix_spawn( )调用启动了名为find_code的程序。程序find_code必须是操作系统可以在计算机上找到的二进制可执行程序。在本例中,find_code是实现示例4-1的基本思想的独立程序。当执行程序清单4-1中的程序时,操作系统生成3个进程。回想一下,是操作系统而不是程序将进程指派到内核和CPU上来执行。进程可以同时执行。两个进程与find_code程序关联,第三个进程是名为posix_spawn( )的进程。作为调用posix_spawn的结果而产生的进程被称作子进程。
注意:
我们将在第5章中详细介绍posix_spawn( )。
程序概要4-1
程序名:
- guess_it.cc(程序清单4-1)
posix_spawn( )启动名为find_code的程序。find_code是一个独立程序,实现示例4-1的基本思想。程序使得操作系统生成3个同时执行的进程。两个进程执行find_code程序,第三个进程执行posix_spawn( )。
必需的库:
无
必需的用户定义头文件:
无
编译和链接指令:
- c++ -o guess_it guess_it.cc
测试环境:
- Linux Kernel 2.6
- Solaris 10、gcc 3.4.3和3.4.6
处理器:
- Multicore Opteron、UltraSparc T1和Cell Processor
注释:
无
值得注意的是,由posix_spawn所产生的子进程总是存在于调用程序之外的二进制可执行程序。不像pthread_create( )调用程序内的例程那样,posix_spawn( )使用存在于调用程序之外的代码。
每个操作系统环境各自有着独特的方法来产生子进程。posix_spawn( )方法能够在有着适当的POSIX兼容的操作环境中使用。因此,您可以构建用于进程创建的跨平台组件。
调用posix_spawn( )的进程被称作父进程。这样,操作系统创建了两个子进程和一个父进程。如果两个内核都空闲,那么操作系统可以指派3个进程中的两个来同时执行。现在您意识到,尽管已经将列表分成两半,而且有两个搜索同时进行,但是仍不确定能够及时在两百万种可能中找到编码,因此您需要再一次地将列表进行分割。这样就得到了4个列表,每个列表包含一百万种编码,并发搜索所需要的时间就会更短一些。当然,您能够在5分钟之内在包含一百万种可能编码的列表中找到目标编码。为了生成4个搜索,可以将find_code程序分为两个执行线程。这样,主程序为程序清单4-1中的guess_it,它产生两个child_processes来执行find_code程序。find_code程序创建两个名为task 1和task 2的线程。程序清单4-2是新的多线程版本的find_code。