1

Here is my class.h

class threads_queue{
private:
    boost::condition_variable the_condition_variable;
public:
    //boost::atomic<bool> done;
    boost::lockfree::spsc_queue<std::pair<char, std::string>> q{100};
    //threads_queue() : done(false) {};
    void static run_function();
    void add_query(std::string, std::string);
    void get_query(void);

};

& Here is class.cpp

void threads_queue::get_query(void){
    std::pair<char, std::string> value;
    //to do..
}


void threads_queue::add_query(std::string str, std::string work){
    //to do .. 

}

void run_function(){
   //Here I want to create two threads 
  //First thread like 
  boost::thread producer_thread(add_query);
  boost::thread consumer_thread(get_query);

  producer_thread.join();
  //done = true;
  consumer_thread.join()
}

I'm following this example: http://www.boost.org/doc/libs/1_54_0/doc/html/lockfree/examples.html

But the problem is when I want to create a thread I always get an error, it does not work

Here were my attempts to solve the error:
1.

boost::thread consumer_thread(&threads_queue::get_query);

I got this error:

Called object type 'void (threads_queue::*)()' is not a function or function pointer

2.

boost::thread consumer_thread(&threads_queue::get_query, this); 

I got this error:

Invalid use of 'this' outside of a non-static member function

3.

  boost::thread* thr = new boost::thread(boost::bind(&threads_queue::get_query));

I got this error:

/usr/local/include/boost/bind/bind.hpp:75:22: Type 'void (threads_queue::*)()' cannot be used prior to '::' because it has no members

I am not how could this problem be solved, any help?

UPDATE This topic has great discussion of the problem: Using boost thread and a non-static class function

My main problem was I forgot to add

threads_queue:: 

before the run() in my cpp file, there are Mikhail comments below where were a great help: .

Community
  • 1
  • 1
Wanderer
  • 1,065
  • 5
  • 18
  • 40

1 Answers1

0

There is a lot wrong with your code.

  1. Non-static members are specific to a class. In addition to the function you need to pass an instance of the class to boost::thread's constructor. This has nothing to do with threads or boost.

  2. threads_queue should "own" the threads, and probably should be renamed to something like thread container. The whole class should at minimal be non-copyable.

Here is a complete example written by somebody other than me.

/  Copyright (C) 2009 Tim Blechmann
//
//  Distributed under the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

//[spsc_queue_example
#include <boost/thread/thread.hpp>
#include <boost/lockfree/spsc_queue.hpp>
#include <iostream>

#include <boost/atomic.hpp>

int producer_count = 0;
boost::atomic_int consumer_count (0);

boost::lockfree::spsc_queue<int, boost::lockfree::capacity<1024> > spsc_queue;

const int iterations = 10000000;

void producer(void)
{
    for (int i = 0; i != iterations; ++i) {
        int value = ++producer_count;
        while (!spsc_queue.push(value))
            ;
    }
}

boost::atomic<bool> done (false);

void consumer(void)
{
    int value;
    while (!done) {
        while (spsc_queue.pop(value))
            ++consumer_count;
    }

    while (spsc_queue.pop(value))
        ++consumer_count;
}

int main(int argc, char* argv[])
{
    using namespace std;
    cout << "boost::lockfree::queue is ";
    if (!spsc_queue.is_lock_free())
        cout << "not ";
    cout << "lockfree" << endl;

    boost::thread producer_thread(producer);
    boost::thread consumer_thread(consumer);

    producer_thread.join();
    done = true;
    consumer_thread.join();

    cout << "produced " << producer_count << " objects." << endl;
    cout << "consumed " << consumer_count << " objects." << endl;
}
//]
Mikhail
  • 7,749
  • 11
  • 62
  • 136
  • This is the same code I mentioned I'm following in my post http://www.boost.org/doc/libs/1_54_0/doc/html/lockfree/examples.html :), but the main difference is that I want to create the thread in a class function rather than main which I'm not able to do until now. Could you please point where the error could be in my code? – Wanderer Mar 13 '17 at 08:05
  • @user7631183 To use a class member you need to bind and instance of the class when you invoke boost::thread. That is, you need to do something like in http://stackoverflow.com/questions/4581476/using-boost-thread-and-a-non-static-class-function – Mikhail Mar 13 '17 at 08:10
  • I have already tried that in the 3rd attempt if you check it, but that did not work – Wanderer Mar 13 '17 at 08:15
  • @user7631183 No you didn't. You need to make an instance of the object before you can bind. Its outlined in http://stackoverflow.com/a/4581516/314290 – Mikhail Mar 13 '17 at 08:15
  • Could you please elaborate? I did not get your point – Wanderer Mar 13 '17 at 08:17
  • My case is exactly the same as the second case in here: http://stackoverflow.com/a/4581516/7631183, I'm in a member class creating a thread of another when I did the same 'boost::thread* thr = new boost::thread(boost::bind(&threads_queue::get_query, this));' , I got this error " Invalid use of 'this' outside of a non-static member function" – Wanderer Mar 13 '17 at 08:20
  • 1
    @user7631183 boost::thread* thr = new boost::thread(boost::bind(&Foo::some_function, &f)); – Mikhail Mar 13 '17 at 08:21
  • that solved the problem, thank you – Wanderer Mar 13 '17 at 08:24