4.1.5 应用程序员的接口(3)
程序清单4-2
- //Listing 4-2 A multithreaded version of the find_code program.
-
- 1 #include <pthread.h>
- 2 using namespace std;
- 3 #include <iostream>
- 4 #include <fstream>
- 5 #include "posix_queue.h"
- 6 string MagicCode("yyzzz");
- 7 ofstream Fout1;
- 8 ofstream Fout2;
- 9 bool Found = false;
- 10 bool magicCode(string X)
- 11 {
- 12 //...
- 13
- 14 return(X == MagicCode);
- 15 }
- 16
- 17
- 18
- 19 void *task1(void *X)
- 20 {
- 21 posix_queue PosixQueue;
- 22 string FileName;
- 23 string Value;
- 24 if(PosixQueue.open()){
- 25 PosixQueue.receive(FileName);
- 26 ifstream Fin(FileName.c_str());
- 27 string FileOut(FileName);
- 28 FileOut.append(".out");
- 29 Fout1.open(FileOut.c_str());
- 30 while(!Fin.eof() && !Fin.fail() && !Found)
- 31 {
- 32 getline(Fin,Value);
- 33 if(!Fin.eof() && !Fin.fail() && !Found){
- 34 if(magicCode(Value)){
- 35 Found = true;
- 36 }
- 37 }
- 38 }
- 39 Fin.close();
- 40 Fout1.close();
- 41 }
- 42 return(NULL);
- 43 }
- 44
- 45
- 46
- 47 void *task2(void *X)
- 48 {
- 49
- 50 posix_queue PosixQueue;
- 51 string FileName;
- 52 string Value;
- 53 if(PosixQueue.open()){
- 54 PosixQueue.receive(FileName);
- 55 ifstream Fin(FileName.c_str());
- 56 string FileOut(FileName);
- 57 FileOut.append(".out");
- 58 Fout2.open(FileOut.c_str());
- 59 while(!Fin.eof() && !Fin.fail() && !Found)
- 60 {
- 61 getline(Fin,Value);
- 62 if(!Fin.eof() && !Fin.fail() && !Found){
- 63 if(magicCode(Value)){
- 64 Found = true;
- 65 }
- 66 }
- 67 }
- 68 Fin.close();
- 69 Fout2.close();
- 70 }
- 71 return(NULL);
- 72 }
- 73
- 74
- 75
- 76
- 77
- 78 int main(int argc, char *argv[])
- 79 {
- 80
- 81 pthread_t ThreadA, ThreadB;
- 82 pthread_create(&ThreadA,NULL,task1,NULL);
- 83 pthread_create(&ThreadB,NULL,task2,NULL);
- 84 pthread_join(ThreadA,NULL);
- 85 pthread_join(ThreadB,NULL);
- 86 return(0);
- 87
- 88 }
第82行和第83行的pthread_create( )函数用于为task1和task2创建线程(我们将在第6章中详细介绍POSIX pthread功能)。程序清单4-2中的程序仅用于说明的目的,其中并不包含任何同步、异常处理、信号处理等。我们将它包含在这里,目的是让您对示例4-1中介绍的guess_it程序的结构有一个清晰的认识。注意第19行中的task1和第47行的task2是正常的C++(www.cppentry.com)函数。它们被用作ThreadA和ThreadB的主例程。还要注意第24行和第53行中这两个线程访问PosixQueue。PosixQueue是一个用户定义对象,它含有每个线程将要进行查找的不同文件名。
这样,程序清单4-1中的程序产生两个子进程。每个进程执行find_code,find_code又依次创建两个线程。这样一共产生了4个线程,每个线程从PosixQueue对象中读取出一个文件名。因此,不再是有一个包含4 496 388种可能的大的文件,而是有4个包含稍大于一百万种可能的较小的文件。您将让每个线程使用简单的穷尽搜索,其中之一将会找到我所想的MagicCode。由于在程序清单4-2的第9行声明了Found变量,这里属于ThreadA和ThreadB的文件作用域或全局作用域,因此可用作控制变量来令两个线程停止。但是第二个进程中的其他两个线程怎么办?程序中使用PosixQueue来将文件名传递给两个进程和所有4个线程。一旦一个线程找到了MagicCode,是否能够使用队列来另外3个进程和4个线程及时知道应当停止呢?
程序概要4-2
程序名:
- find_code.cc(程序清单4-2)
描述:
程序find_code创建名为task1和task2的两个线程。每个线程访问PosixQueue。这是一个用户定义对象,它包含每个线程将要进行编码搜索的不同文件名。
必需的库:
- pthread
必需的用户定义头文件:
- posix_queue.h
编译和链接指令:
- c++ -o find_code find_code.cc posix_queue.cc -lpthread -lrt
测试环境:
- Linux Kernel 2.6
- Solaris 10、gcc 3.4.3和3.4.6
处理器:
- Multicore Opteron、UltraSparc T1和Cell Processor
注释:
无