pthread中使用pthread_create创建线程:
1 2 3 4 5 6 7 8 | void* worker(void *args) { //~ thread execution. return NULL; } pthread_t tid; //~ pthread_create(pthread_t*, pthread_attr_t*, void*(*)(void*), void*); pthread_create(&tid, NULL, worker, NULL); |
其中,线程函数worker就是所创建线程将要执行的代码。当然,由于同一进程中各线程的代码段是共享的,所以在线程函数中可以像普通函数那样合法地调用其他函数。
有时候,我们可能想要将一个类的成员函数作为一个单独的线程来执行,甚至在某个类中控制线程的执行。但我们并不能直接使用成员函数来创建线程,像下面一样,
1 2 3 4 5 6 7 8 9 10 11 | class Thread { public: void* worker(void* args) { //~ thread execution. } private: //~ here some data member. }; pthread_t tid; pthread_create(&tid, NULL, &Thread::worker, NULL); |
编译上面代码,会得到类似
error: cannot convert ‘void* (Thread::*)(void*)’ to ‘void* (*)(void*)’ for argument ‘3’ to ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)’
的错误信息,意思是说,对于pthread_create的第三个参数,无法将void* (Thread::*)(void*)转化为void* (*)(void*)类型。我们知道,类的普通成员函数的执行是绑定到某一个具体的对象上面的,除了我们声明的参数之外,还需要一个’多余’的参数this来指明该函数的本次执行所绑定到的对象。
我们还知道,类的静态成员函数是不需要绑定到特定对象上面的,所以我们就可以将worker声明为静态成员。
1 2 3 4 5 6 7 8 9 10 11 | class Thread { public: static void* worker(void* args) { //~ thread execution. } private: //~ here some data member. }; pthread_t tid; pthread_create(&tid, NULL, &Thread::worker, NULL); |
我们又知道,静态成岩函数是不能’直接’访问类的非静态成员(包括函数),因此,上面代码中worker即使属于class Thread的类域,但却无法访问这个类的成员,这让人十分不爽。哪位大牛说过来着?任何一个复杂的计算机问题,都可以通过中间层来解决。这里也可以建立一个中间层:使用静态成员函数创建线程,给该函数传递某个对象的地址作为参数,在该静态函数中就可以通过所传递对象的使用它的任何成员了。
我比较喜欢使用的是类似这样的一个抽象类,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | class Thread { public: virtual ~Thread() {} pthread_t start() { pthread_t tid; pthread_create(&tid, NULL, hook, this); return tid; } private: void* hook(void* args) { reinterpret_cast<Thread*>(args)->worker(); return NULL; } protected: virtual void worker() = 0; }; |
继承这个类,实现worker函数就行了。调用start启动线程,各线程共享对象的数据。
你好!除了代码,此处没有多少原创之物,皆为本人搜集、整理、总结之记录与心得,欢迎转载分享!转载时请尽量注明出处,将不胜感激。祝你健康、快乐!