3

对于给定的程序::

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 )' 的无效转换</p>

我基本上想将每个 object NodeObj[0], NodeObj[1], NodeObj[2]... 发送到我创建的每个新线程。start 函数是每个线程开始的地方。

4

4 回答 4

4

这可能会做你想要的。我只是把它放在一起,所以如果有任何语法错误,我提前道歉。它解决了您的两个问题(不正确的第三个和第四个参数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
于 2013-03-30T09:39:56.007 回答
2

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

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

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

与函数被声明为第三个参数的内容不匹配。

将您的开始更改为:

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

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

于 2013-03-30T09:26:02.797 回答
2

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

thread_start 函数签名是

void * thread_start(void *arg)

In the main function you can see how to pass arguments (&tinfo[tnum]).

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

Note that each thread recieves a distinct set of arguments.

于 2013-03-30T09:40:44.857 回答
1

The return type of the thread function must be void *;

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

Secondly, you must send the argument to the function this way:

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

The requirement of argument passing is that the passed object must be a pointer to something. Even though nodeObj is a pointer, when you use array notation like nodeObj[i] you dereference it. Hence use the ampersand. &nodeObj[i];

You can also simply use (nodeObj+i);

于 2013-03-31T04:58:15.560 回答