2016-09-21 92 views
1

我想调用一个带有多线程的函数,而且我只需要传递一个整数给该函数(线程ID,所以如果它是可访问的,我不需要任何值通过)。在C++中传递一个整数到一个多线程函数

我应该怎么做?

例如像:

其中
for(int i=0; i < numberOfThread; i++){ 
     pthread_create(&threads[i], NULL, multichaper, &td[i]); 
} 

multichaper是我的功能和线程ID是与整数。

更新:我将user3286661的答案标记为正确的答案,对我而言,如果您想要更详细的答案,您可以在答案中检查我自己的解决方案。

回答

1

一般的方法来这是为了让这样的功能:

void* multichaper(void* arg) { 
    int tid = *(int*)arg; 
    ... 
} 

而且同时呼吁pthread_create

pthread_create(&threads[i], NULL, multichaper, &td[i]) 

其中td[i]int

+0

非常感谢,该作品 – ameerosein

+0

@ameerosein:你能*保证*线程将在'td [i]'超出范围之前结束吗?当你在调试器中进行测试时,或者甚至在测试时很容易做到这一点 - 但是对于你传递给'multichaper'的地址在线程有机会读取之前消失的事情重载生产服务器。 –

+0

@ user3286661你可以检查这个问题吗? http://stackoverflow.com/questions/39656285/how-to-multithreading-a-function-of-a-class-with-pthreads – ameerosein

-1

如果您只想传递一个id给调用线程,您可以通过将其掩埋在void*参数中来实现,并且这样做是可移植的。像,

pthread_create(&threads[i], NULL, multichaper, (void*)threadID); 
+2

为什么你认为是便携式?首先,不能保证'void *'足够大以容纳'int'。其次,不能保证将int转换为'void *'不会改变位模式(我已经使用过我希望它可以这样做的机器 - 它会在环数中使用OR) –

1

不,你不能这样做。您传递给pthread_create的功能必须有签名void *(*start_routine) (void *)。也就是说,一个函数将一个非const指针指向void并将一个非const指针返回为void。

最简单的方法是一样的东西:

int *arg = new int(threadID); 
pthread_create(&threads[i], NULL, multichaper, threadID); 

然后multichaper是这样的:我已经在堆中分配的INT,以避免不必担心变量寿命

void *multichaper(void *arg) 
{ 
    int *pint = static_cast<int*>(arg); 
    int threadID = *pint; 
    delete pint; 
    ... 
    return nullptr; 
} 

注意。如果您可以保证调用函数中的变量threadID将超过该线程,那么您可以跳过该位。

我强烈建议您使用C + 11和内置的线程库,或者如果您不能这样做,请使用boost :: threads。他们都让这更容易!

+0

我认为你对物体寿命的压力是非常重要的。好答案。 –

1

你真的应该考虑迁移到C++ 11个线程:

#include <thread> 
#include <iostream> 

void show_id(int id) { 
    std::cout << id << std::endl; 
} 

int main() 
{ 
    std::thread t(show_id, 10); 
    t.join(); 
} 

如果必须使用并行线程,虽然:

#include <iostream> 
#include <pthread.h> 

void *show_id(void *x_void_ptr) 
{ 
    const int id = *static_cast<int *>(x_void_ptr); 

    std::cout << id << std::endl; 

    return NULL; 
} 

int main() 
{ 
    pthread_t t; 

    int id = 10; 
    if(pthread_create(&t, NULL, show_id, &id)) { 
     std::cerr << "couldn't create" << std::endl; 

     return -1; 
    } 

    if(pthread_join(t, NULL)) { 
     std::cerr << "couldn't join" << std::endl; 

     return -2; 
    } 
} 

注意的第一个版本是如何更好地:

  1. 没有演员表

  2. 更少明确检查

  3. 与您传递对象的生存期没问题 - 在第一个版本,你传递它的指针,因此必须确保它的“活着”,而线程正在使用它。

  4. 没有不直观的void *返回(具有相同的生命期问题)。

+0

你能否检查这个问题呢? http://stackoverflow.com/questions/39656285/how-to-multithreading-a-function-of-a-class-with-pthreads?noredirect=1#comment66615110_39656285 – ameerosein

0

正如我想通过使整数a struct内部和锁定(lock_mutex),其以号码传递从0到NumberOfThreads到我的函数I最终使用下面的代码,试图检索threadNum时:

在调用多线程功能SVAnchor类的成员函数:

pthread_t threads[this->numberOfThread]; 
pthread_attr_t attr; 

params_t params; 
pthread_mutex_init (&params.mutex , NULL); 
pthread_cond_init (&params.done, NULL); 

pthread_attr_init(&attr); 
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 
for(int i=0; i < this->numberOfThread; i++){ 
    params.id = i; 
    params.ptr = this; 
    rc = pthread_create(&threads[i], NULL, &(SVAnchor::multichaperWrapper), &params); 
    pthread_cond_wait (&params.done, &params.mutex); 
} 
pthread_attr_destroy(&attr); 
void* status; 
for(int i=0; i < this->numberOfThread; i++) 
    rc = pthread_join(threads[i], &status); 
pthread_mutex_destroy (&params.mutex); 
pthread_cond_destroy (&params.done); 

params_t如下:

struct params { 
    SVAnchor* ptr; 
    pthread_mutex_t mutex; 
    pthread_cond_t done; 
    int id; 
}; 
typedef struct params params_t; 

然后multichaperWrapper如下:

void* SVAnchor::multichaperWrapper(void* arg){ 
    return (((params*)arg)->ptr)->multichaper( ((params*)arg)); 
} 

multichaper如下:

void* SVAnchor::multichaper(void *threadarg /*0 <= threadNum < numberofthreads*/){ 
    int threadNum; 
    /* Lock. */ 
    pthread_mutex_lock(&(*(params_t*)(threadarg)).mutex); 

    /* Work. */ 
    threadNum = (*(params_t*)(threadarg)).id; 


    /* Unlock and signal completion. */ 
    pthread_mutex_unlock(&(*(params_t*)(threadarg)).mutex); 
    pthread_cond_signal (&(*(params_t*)(threadarg)).done); 
    cout<<threadNum<<endl; 
    ... 
} 
相关问题