简体   繁体   中英

c++ - Passing vector to thread

I am getting error like below on passing vector via pthread_create as given below.

#include <iostream>
#include <pthread.h>
#include <vector>
using namespace std;

void foo(void *a)
{
  vector <int> b = (vector <int>*)a;

  for(int i=0; i<b.size(); i++)
  {
        std::cout<<b[i];
  }
  return NULL;
}

void bar(int x)
{
  std::cout<<"bar";
}

int main()
{
  pthread_t thr;
  std::vector <int> a = {1,2,3};
  pthread_create(&thr, NULL, &foo, (void *)&a);
  pthread_join(thr,NULL);
  return 0;

Error messages :

threadeg.cpp: In function ‘void foo(void*)’:
threadeg.cpp:9:35: error: conversion from ‘std::vector<int>*’ to non-scalar type ‘std::vector<int>’ requested
   vector <int> b = (vector <int>*)a;

threadeg.cpp:16:10: error: return-statement with a value, in function returning 'void' [-fpermissive]
   return NULL;
          ^
threadeg.cpp: In function ‘int main()’:
threadeg.cpp:28:46: error: invalid conversion from ‘void (*)(void*)’ to ‘void* (*)(void*)’ [-fpermissive]
   pthread_create(&thr, NULL, &foo, (void *)&a);

/usr/include/pthread.h:244:12: error:   initializing argument 3 of ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)’ [-fpermissive]
 extern int pthread_create (pthread_t *__restrict __newthread,

I am new to threads and I m unable to figure out what is going wrong. Can anyone point out the problem and suggest a solution?

First you have some mistakes that a void function doesn't return anything. In your case it returns NULL . NULL is nothing but zero by definition. So returning NULL does not mean returning nothing.

bar() function is unnecessary.

Now check the working code.

#include <iostream>
#include <pthread.h>
#include <vector>
using namespace std;

void *foo(void *a)
{
   vector <int>* b = (vector <int>*)a;

   for (auto it : *b) {
   std::cout << it;
   }
}

int main()
{
  pthread_t thr;
  std::vector <int> a;
  a.push_back(1);
  a.push_back(2);
  a.push_back(3);
  pthread_create(&thr, NULL, &foo, &a);
  pthread_join(thr,NULL);
  return 0;
}

You're going to send the address of your vector. And also you will have a void * returning function, not void returning function. You're similarly going to send the address of it.

there is few little mistake i think you wanted to create a pointer b not a copy vector <int>* b = (vector <int>*)a; . The function foo signature should be void* foo (void* a) not void foo(void* a)

You should cast a to vector <int>* b or to reference like below because you're passing a pointer and you try to assign it to an object.

Change foo 's return to (void*) because pthread_create expects void *(*start_routine) (void *) .

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

using namespace std;

void* foo(void *a)
{
  const vector <int>& b = *(vector <int>*)a; // Cast to a reference or pointer, could be made const

  for(int i=0; i<b.size(); i++)
  {
        std::cout<<b[i];
   }
    return NULL;
}

void bar(int x)
{
  std::cout<<"bar";
}

int main()
{
  pthread_t thr;
  std::vector <int> a = {1,2,3};
  pthread_create(&thr, NULL, &foo, (void *)&a);
  pthread_join(thr,NULL);
  return 0;
}

You can try it here https://ideone.com/S1bWSk .

UPDATE And yes, it would be better if you switch to std::thread if you can. And you can pass your array by reference.

void foo(const vector <int>& b)
{
   for(int i=0; i<b.size(); i++)
   {
        std::cout<<b[i];
   }
}

....

std::thread thr(foo, std::cref(a));
thr.join();

Since there is no answer (just a comment) recommending to use std::thread instead of POSIX functions I want to show this alternative. It also solves/prevents a lot of the other errors in the text, and it is far easier to use.

#include <iostream>
#include <thread>
#include <vector>

using namespace std;

void foo(std::vector<int> const& b)
{
  for(int i=0; i<b.size(); i++)
  {
        std::cout<<b[i];
  }
}

void bar(int x)
{
  std::cout<<"bar";
}

int main()
{
  std::vector <int> a = {1,2,3};
  std::thread thr(a, foo);
  thr.join();
  return 0;
}

There is a small difference worth mentioning. The vector gets copied when the thread object is created. This can be avoided by using std::cref , or by using a lambda with the appropriate capture.

When needed you can get the thread handle with std::thread::native_handle() and pass this to POSIX functions like pthread_getcpuclockid :

std::thread thr(a, foo);
clockid_t clk;
pthread_getcpuclockid(thr.native_handle(), &clk);

I would encapsulate the calls to legacy functions and not use native_handle outside this encapsulation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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