繁体   English   中英

pthread将对象作为参数传递给pthread_create

[英]pthread passing object as argument to 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;   
}

我收到以下错误::

从'void( )(void )'到'void *( )(void )'的无效转换

我基本上想要将每个对象NodeObj[0]NodeObj[1]NodeObj[2] ...发送给我创建的每个新线程。 start函数是每个线程开始的位置。

这可能会做你想要的。 我只是把它扔在一起,所以如果有任何语法错误,我会提前道歉。 它解决了您的两个问题( 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线程类和对象(线程,互斥,条件变量等)而不是使用raw-pthreads。 他们真的是蜜蜂的膝盖。 类似的东西(尽管有自动计算的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

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

您的代码将第三个参数作为开头传递。

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

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

将您的开始改为:

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

会使错误消失。 除非您调用pthread_exit ,否则从该方法返回的值将充当线程的退出代码。

pthread_create()的linux手册页包含一个很好的例子。

thread_start函数签名是

void * thread_start(void *arg)

在main函数中,您可以看到如何传递参数( &tinfo [tnum] )。

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

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

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

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

其次,您必须以这种方式将参数发送到函数:

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

参数传递的要求是传递的对象必须是指向某事物的指针。 即使nodeObj是一个指针,当你使用像nodeObj [i]这样的数组表示法时,你会取消引用它。 因此使用&符号。 &nodeObj [I];

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM