0

I am trying to implement spsc_queue of boost.

But initialising thread throws error. I cant use both std::thread as well as boost thread.

sharedQueue.hpp `

#include <stdio.h>
#include <iostream>
#include <queue>
#include <thread>
#include <mutex>
#include <boost/thread.hpp>
#include <boost/lockfree/spsc_queue.hpp>
using namespace std;
class sharedQueue
{
boost::lockfree::spsc_queue<int> lockFreeQ{100};

std::queue<int> comQue;
int head =0;;
int tail = 0;

public:

sharedQueue();

std::mutex lockForQueue;

void write(int writeValue);
int read();

void startTesting();

void TestWrite(int MaxElement);

void lockFreeProduce();
void lockFreeConsume();
void TestLockFreeQueue();    
};`

Following is the sharedQueue.cpp

#include "sharedQueue.hpp"
 int sharedQueue :: read(){    
int readValue;
lockForQueue.lock();
if(!(comQue.empty()))
{
readValue = comQue.front();
comQue.pop();
}
lockForQueue.unlock();
return readValue;
}

void sharedQueue :: write(int writeValue){
lockForQueue.lock();

comQue.push(writeValue);
tail++;
lockForQueue.unlock();
} 

void sharedQueue:: startTesting(){

std::cout<<"Size of the que --"<<comQue.size()<<std::endl;
}

void sharedQueue:: TestWrite(int maxEle ){

for(int i = 0 ; i < maxEle; i ++){
    write(i);
}
}
void sharedQueue::lockFreeProduce(){

for(int i = 0; i < 10; i++){

    cout <<“Produced--    "<< i<<endl;
    lockFreeQ.push(i);
}
}
void sharedQueue::lockFreeConsume(){

for(int i = 0;  i <10; i++){
    lockFreeQ.front();

   cout << “  Consume-- "<<lockFreeQ.pop();    
}
}
void sharedQueue:: TestLockFreeQueue(){

std::thread t1(lockFreeProduce);

std::thread t2(lockFreeConsume);

t1.join();
t2.join();  
} `

I am using Xcode. I have tried changing C++ Language dialect to c++11 from GNU++11 Standard Library to libc++11 from libstdC++

Please help.

Where am I doing wrong?

Kid
  • 169
  • 1
  • 19
  • What is the error ? And why do you want to use both boost thread and the one provided by your standard library impl ? – Arunmu Nov 22 '16 at 17:50
  • No matching constructor to initialisation of boost::thread. I tried to create thread using boost as well as standard thread. But both throws the same error. – Kid Nov 23 '16 at 09:21
  • 1
    Try `std::thread t1([this] () { this-> lockFreeProduce(); });` – Arunmu Nov 23 '16 at 09:46
  • Yes it works fine now. could you please explain me the problem. and “[this] () { this-> lockFreeProduce(); }” this structure? – Kid Nov 23 '16 at 11:16
  • Have added it as answer. – Arunmu Nov 23 '16 at 11:35

1 Answers1

0

You are trying to run a member function as a new thread, not a plain old function. The syntax for member function is different.

void sharedQueue:: TestLockFreeQueue(){
    std::thread t1(std::bind(&sharedQueue::lockFreeProduce, this));
    std::thread t2(std::bind(&sharedQueue::lockFreeConsume, this));

    t1.join();
    t2.join();  
} 

Below answer assumes that we are talking about non-static member function. static member function behaves kind of same way as that of a normal function pointer.

A member function pointer is complex than a plain old function pointer and it cannot be invoked in standalone manner i.e it can only be called when there is an object instance of that class.

See this for an example and read this for better understanding of member function pointers.

An easier way to do it i.e instead of using bind to create a callable object is to use a lambda, C++11 onwards and you should prefer lambda over bind whenever and however possible.

Your example using a lambda:

void sharedQueue:: TestLockFreeQueue(){
   std::thread t1([this]() { this->lockFreeProduce(); });
   std::thread t2([this]() { this->lockFreeConsume(); });

   t1.join();
   t2.join();  
} 

Here I am passing a lambda to the constructor of the thread which creates an anonymous functor structure. The square bracket [...] is the capture list which copies this pointer so that it can be used inside a lambda.

More about lambda can be found here and here.

Community
  • 1
  • 1
Arunmu
  • 6,837
  • 1
  • 24
  • 46