歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 為什麼類中的線程函數必須要聲明靜態

為什麼類中的線程函數必須要聲明靜態

日期:2017/3/1 9:05:19   编辑:Linux編程

其實類的靜態函數就跟全局函數是一個樣子的, 只是調用的時候要加下個類修飾符而已。至於為什麼不能是非靜態成員函數呢, 因為非靜態成員函數都會在參數列表中加上一個this指針為為參數, 這樣的話你寫的線程函數就不符合調用規定了。

比如 DWORD WINAPI ThreadFun(LPVOID); 是非靜態的,實際編譯後,就會變成

DWORD WINAPI ThreadFun(LPVOID, CMyClass *this);

這個函數就明顯不能作為線程的函數了, 因為多了個參數.所以編譯就過不了了.

它與設置成全局函數有一個好處:就是不用聲明為friend成員即可訪問對象的私有成員。

成員變量不用改成static的,你創建線程的時候把對象的“this”指針作為參數傳遞過去,就可訪問了。

#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

class Thread
{
private:
pthread_t pid;
private:
static void * start_thread(void *arg);// //靜態成員函數
public:
int start();
virtual void run() = 0; //基類中的虛函數要麼實現,要麼是純虛函數(絕對不允許聲明不實現,也不純虛)
};

int Thread::start()
{
if(pthread_create(&pid,NULL,start_thread,(void *)this) != 0) //´創建一個線程(必須是全局函數)
{
return -1;
}
return 0;
}

void* Thread::start_thread(void *arg) //靜態成員函數只能訪問靜態變量或靜態函數,通過傳遞this指針進行調用
{
Thread *ptr = (Thread *)arg;
ptr->run(); //線程的實體是run
}

class MyThread:public Thread
{
public:
void run();
};
void MyThread::run()
{
printf("hello world\n");
}

int main(int argc,char *argv[])
{
MyThread myThread;
myThread.start();
//test.run();
sleep(1);
return 0;
}

編譯運行:

linuxidc@Ubuntu:~/myProg/pthreadCpp$ g++ main.cpp -lpthread
linuxidc@ubuntu:~/myProg/pthreadCpp$ ./a.out
hello world
linuxidc@ubuntu:~/myProg/pthreadCpp$

有一個更加好的方法,就是使用boost::thread,結合boost::function,boost::bind很方便的實現類成員函數線程化

1.如何創建簡單的線程

#include <boost/thread/thread.hpp>
#include <iostream>
using namespace std;

void helloworld()
{
cout << "hello world" << endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
boost::thread thd(&helloworld);
thd.join();//等線程結束
}

2.如何給線程攜帶參數

#include <boost/thread/thread.hpp>
#include <boost/bind.hpp>
#include <string>
#include <iostream>
using namespace std;

void helloworld(string par1, int par2, double par3)
{
cout << "hello world" << endl;
cout << par1 << "," << par2 << "," << par3 << endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
boost::thread thd(boost::bind(&helloworld,string("haha"),1,1.0));
thd.join();//等線程結束
}

3.如何線程互斥

#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <iostream>
using namespace std;

boost::mutex mutex_;
int io_;
void thread_in()
{
boost::mutex::scoped_lock lock(mutex_);
cout << "in " << io_++ << endl;
}
void thread_out()
{
boost::mutex::scoped_lock lock(mutex_);
cout << "out " << io_-- << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
boost::thread thd1(&thread_in);
boost::thread thd2(&thread_out);
thd1.join();
thd2.join();
io_ = 0;

}

4.如何讓類成員函數線程化

#include <boost/thread/thread.hpp>
#include <string>
#include <iostream>
using namespace std;

class myclass
{
public:
myclass():
classname_("I am Hero")
{

}
protected:
string classname_;
protected:
void handle_thread()
{
cout << classname_ << endl;
}
};

int _tmain(int argc, _TCHAR* argv[])
{
myclass c;
boost::thread thd(boost::bind(&myclass::handle_thread,&c));
thd.join();
}

Copyright © Linux教程網 All Rights Reserved