4.3.2 POSIX API的接口类(1)
令POSIX API透明的最容易的方法是提供C++(www.cppentry.com)接口类。接口类是提供函数、数据或其他类的包装的类。接口类就像某种装束一样,使得某个物体看上去跟平常时候不一样。接口类改变函数、数据、另一个类的外观。接口类也被称作适配类。接口类提供的新的接口被设计为令类更易于使用、更具功能性、更安全或语义正确。以程序清单4-2中第81行~第85行所显示的POSIX线程函数为例,我们希望这个程序的主线不要暴露操作系统调用,而且希望对guess_it程序加入更多的C++(www.cppentry.com)面向对象风格。程序清单4-3包含了程序清单4-2中的find_code程序的新的实现。
程序清单4-3
- //Listing 4-3 A more object-oriented find_code: ofind_code.
-
- 1 #include "thread_object.h"
- 2
- 3
- 4 int main(int argc, char *argv[])
- 5 {
- 6
- 7
- 8
- 9 user_thread Thread[2];
- 10 Thread[0].name("ThreadA");
- 11 Thread[1].name("ThreadB");
- 12 for(int N = 0; N < 2;N++)
- 13 {
- 14 Thread[N].run();
- 15 Thread[N].join();
- 16 }
- 17 return(0);
- 18
- 19 }
程序清单4-3中的代码替换了程序清单4-2代码中的第78行~第88行。尽管没有减少代码行数,但是我们改变了线程创建和执行过程的接口。现在使用一个user_thread类来封装pthread_t线程的id以及其他一些pthread函数。现在我们是声明对象并调用方法,而不是调用POSIX API函数。程序清单4-3中的程序用于创建并执行两个线程,然后在退出之前与线程结合。在程序清单4-2中可以较容易地看出线程将要做些什么工作,但是在程序清单4-3中,线程在做些什么不是很明显。在程序清单4-2的第82行和第83行,调用了pthread_create,并将函数task1和task2的名称传递给它,它们将会被ThreadA和ThreadB执行。在程序清单4-3中,由于封装的缘故,ThreadA和ThreadB将执行什么就不是很明显。我们只能够看到调用了run( )方法。为了更好地理解程序清单4-3如何替代程序清单4-2,需要看一下程序清单4-3的第一行中包含的thread_object.h中的声明。在头文件thread_object.h中包含名为thread_object的抽象类。我们知道它是一个抽象类,是因为在程序清单4-4的第14行中声明的抽象虚方法。
程序概要4-3
程序名:
- ofind_code.cc(程序清单4-3)
描述:
程序清单4-3中的程序创建并执行两个线程。然后它在退出之前与这些线程结合。run( )方法调用要执行的任务。用程序清单4-3取代程序清单4-2,请在thread_object.h中查看声明。
必需的库:
- rt,pthread
需要的其他源文件:
- thread_object2.cc(程序清单4-5),user_thread.cc(程序清单4-6)
必需的用户定义头文件:
- thread_object.h(程序清单4-4),posix_queue.h
编译和链接指令:
- c++ -o ofind_code ofind_code.cc user_thread.cc thread_object.cc posix_queue.cc -lrt -lpthread
测试环境:
- Linux Kernel 2.6
- Solaris 10、gcc 3.4.3和3.4.6
处理器:
- Multicore Opteron、UltraSparc T1和Cell Processor
注释:
无
程序清单4-4
- //Listing 4-4 A declaration of a simple thread_object.
-
-
- 1 #ifndef __THREAD_OBJECT_H
- 2 #define __THREAD_OBJECT_H
- 3
- 4 using namespace std;
- 5 #include <iostream>
- 6 #include <pthread.h>
- 7 #include <string>
- 8 #include "posix_queue.h"
- 9
- 10 class thread_object{
- 11 pthread_t Tid;
- 12 string Name;
- 13 protected:
- 14 virtual void do_something(void) = 0;
- 15 public:
- 16 thread_object(void);
- 17 ~thread_object(void);
- 18 void name(string X);
- 19 string name(void);
- 20 void run(void);
- 21 void join(void);
- 22 friend void *thread(void *X);
- 23 };
- 24
- 25
- 26
- 27 class user_thread : public thread_object{
- 28 private:
- 29 posix_queue *PosixQueue;
- 30 protected:
- 31 virtual void do_something(void);
- 32 public:
- 33 user_thread(void);
- 34 ~user_thread(void);
- 35 };
- 36
- 37
- 38 #endif