2013-03-30 80 views
1

对于给定的程序::并行线程传递对象作为参数传递给在pthread_create

void start(void *n){ 
    Node *obj = (Node *)n; 
    cout << obj -> val; 
} 

int 
main(int argc, char *argv[]) 
{ 
    int i,n; 
    cin >> n; 
    Node *nodeObj; 
    nodeObj = new Node[n]; 
    pthread_t *p = new pthread_t[n]; 
    for(i=0;i<n;i++){ 
    pthread_create(&p[i],NULL,start,(void *)(nodeObj[i])); /*ERROR HERE in arg pass*/ 
    }                    
    return 0; 
} 

我收到以下错误::

invalid conversion from ‘void ()(void)’ to ‘void* ()(void)’

我基本上要发送的每个对象NodeObj[0]NodeObj[1]的, NodeObj[2] ...我创建的每个新线程。启动函数是每个线程启动的地方。

+0

使用'nodeObj + i',而不是'nodeObj [I]'。并且在'pthread_create()'调用中抛出cast-to-void *;它只会工作(尽管你可能想**加入**这些线程,并在完成时清理该分配)。 – WhozCraig

+0

嗨@WhozCraig感谢您的快速回复。我试着做你说的话,但我仍然得到以下错误:初始化'int pthread_create(pthread_t *,const pthread_attr_t *,void *(*)(void *),void *)'参数3' –

+2

函数应返回void *,不是void。 – WhozCraig

回答

2

这可能会做你想做的。我只是把它扔在一起,所以我提前道歉,如果有任何语法错误。它涉及您的两个问题(不正确的第三个和第四个参数pthread_create()),以及使用RAII的分配管理:

#include <iostream> 
#include <vector> 

using namespace std; 

struct Node 
{ 
    int value; 
}; 

void *start(void* p) 
{ 
    Node* obj = (Node*)p; 
    cout << obj->value; 
    return NULL; 
} 

int main(int argc, char *argv[]) 
{ 
    int n; 
    cin >> n; 
    if (n <= 0) 
     return EXIT_FAILURE; 

    std::vector<Node> nodes(n); 
    std::vector<pthread_t> threads(n); 
    for (int i=0;i<n;++i) 
     pthread_create(threads.data()+i, NULL, &start, nodes.data()+i); 

    std::for_each(threads.begin(), threads.end(), 
        [](pthread_t& t) { pthread_join(t, NULL); }); 

    return EXIT_SUCCESS; 
} 

C++ 11的话题:他们就是我们的晚饭

我会建议使用C++ 11线程类和对象(线程,mutex,condition_variable等)来使用raw-pthread。他们真的是蜜蜂的膝盖。类似的东西(尽管有自动计算N)如下所示:

#include <iostream> 
#include <vector> 
#include <thread> 
#include <memory> 
using namespace std; 

struct Node 
{ 
    int value; 
    Node() : value() {} 

    // member function we're using as thread proc 
    void thread_proc(int n) 
    { 
     value = n; 
    } 
}; 

int main(int argc, char *argv[]) 
{ 
    // allocate nodes 
    vector<Node> nodes(std::max(std::thread::hardware_concurrency()+1, 4U)); 

    // starts threads 
    vector<thread> threads; 
    for (int i=0; i<nodes.size(); ++i) 
     threads.emplace_back(std::bind(&Node::thread_proc, nodes.data()+i, i+1)); 

    // wait for all threads to complete. 
    for(auto &t : threads) 
     t.join(); 

    // proof we really did hit *our* nodes in the threads. 
    for (auto& node : nodes) 
     cout << "Node value: " << node.value << endl; 

    return EXIT_SUCCESS; 
} 

输出

Node value: 1 
Node value: 2 
Node value: 3 
Node value: 4 
Node value: 5 
2

编译器抱怨参数3,start_routine。开始例程(pthread_create的第三个参数)以这种方式指定:void *(*start_routine)(void *)一个指向方法的指针,它将一个void指针(void *)作为参数并返回一个void指针(void *)。

您的代码传递一个开始作为第三个参数。

void start(void *n){ 
    ... 
} 

函数声明为第三个参数的不匹配。

改变你的开始:

void *start(void *n) { 
    return NULL; 
} 

将错误消失。 从方法返回的值将作为线程的退出代码,除非您致电pthread_exit

2

linux manual page用于在pthread_create()包含一个很好的例子。

的thread_start函数签名是

void * thread_start(void *arg) 

在主函数中你可以看到如何来传递参数(& TINFO [tnum])。

pthread_create(&tinfo[tnum].thread_id, &attr, &thread_start, &tinfo[tnum]); 

请注意,每个线程收到一组不同的参数。

1

线程函数的返回类型必须为void *;

void* start(void *n) 
{ 
//Code 
} 

其次,必须论证这种方式发送给功能:

pthread_create(&p[i],NULL,start,(void *)(&nodeObj[i])); 

参数传递的要求是传递的对象必须是指针的东西。即使nodeObj是一个指针,当你使用像nodeObj [i]这样的数组符号时,你可以将其解引用。因此使用&符号。 & nodeObj [i];

你也可以简单地使用(nodeObj+i);