用pthread傳遞參數格式一般是這樣的:
int pthread_create (pthread_t *tid,const pthread_attr_t *attr,void *(*func)(void *),void *arg)
其中最後一個參數就是用來傳遞參數的,可以是一個簡單的參數,也可以是一個參數集合成的結構體。
由於線程之間使用不同的棧,因此,如果是本地的局部變量作爲參數傳遞到新線程中使用,有可能使參數的值變成未定義的,簡單舉例如下:
struct node_ {
int index;
string name;
}node;
void *thread_callback(void *arg){
node_ *pc = (node_*)arg;
int localIndex = pc->index;
string localName = pc->name;
.....
return NULL;
}
int test(string name){
node_ param;
param.index = 5;
param.name = name;
pthread_t pid; pthread_create(&pid, NULL, thread_callback, (void *)¶m);
......
return 0;
}
上面的例子中,把本地的參數param的地址傳給了新線程,在新線程中會取出該參數使用,這就是把原來線程的局部變量傳遞到新線程中,在新線程中使用該變量時行爲是未定義的,也就是index和name的值都是隨機的,也有可能是無法訪問的地址值,可能導致程序行爲異常或者訪問了非法地址而導致崩潰。
如何正確傳遞參數呢?由於堆是共享的,可以將棧數據轉化爲堆數據,把堆的地址傳遞到新的線程,這樣能夠正確的傳遞變量值。
int test(string name){
node_ *param = new node_;
param->index = 5;
param->name = name;
pthread_t pid; pthread_create(&pid, NULL, thread_callback, (void *)param);
......
return 0;
}
這樣我們會發現,param的地址跟arg的地址是相同的,也就是把堆的一個地址作爲參數傳遞到新線程,從而達到了共享數據的目的。
需要注意的是,新線程中取出數據後需要把指針刪除,防止內存泄露。
也可以將局部變量轉化爲全局變量來傳遞數據。