0
votes

I would like to run a variant of example 46.3 from this website http://theboostcpplibraries.com/boost.lockfree. I am on a linux system.

I would like to have the queue q be defined in a header file. I would like to have the produce and consume functions be in different files. So I would like to have global.h contain

    static boost::lockfree::queue<int> q{100};
    static std::atomic<int> sum{0};
    void *produce (void*);
    void *consume (void*);

I would then like to have a produce.cpp contain:

     void *produce( void*)
         {
            for (int i = 1; i <= 10000; ++i)
q.push(i);

         }

and I would like to have a consume.cpp contain

         void *consume (void*)
         {
                int i;
         while (q.pop(i))
            sum += i;

                     }

I would then like to have my main.cpp contain

         #include iosteam
         #include iomanip
         #include global
         #include pthread

         int main () 
                  {pthread_t t1;
                  pthread_t t2;
                 pthread_t t3;


                           int t1_iret;
                   t1_iret = pthread_create( &t1, NULL, produce, NULL);
          if(t1_iret)
         {
                fprintf(stderr,"Error - pthread_create() return code:  %d\n",t1_iret);
     exit(EXIT_FAILURE);
 }

         int t2_iret;
       t2_iret = pthread_create( &t2, NULL, consume, NULL);
     if(t2_iret)
 {
     fprintf(stderr,"Error - pthread_create() return code: %d\n",t2_iret);
     exit(EXIT_FAILURE);
 }

          int t3_iret;
      t3_iret = pthread_create( &t3, NULL, consume, NULL);
      if(t3_iret)
  {
     fprintf(stderr,"Error - pthread_create() return code: %d\n",t3_iret);
     exit(EXIT_FAILURE);
  }



        pthread_join( t1, NULL);
        pthread_join( t2, NULL);
       pthread_join( t3, NULL);



                       return 0; }

Additionally, I was wondering if it would be possible to do what I have described with strings rather then integers.

edit1: when I try and make the queue be queue of strings I get::

/usr/local/include/boost/lockfree/queue.hpp: In instantiation of ‘class boost::l ockfree::queue >’: /home/ubuntu/Project/src/main.cpp:15:37: required from here /usr/local/include/boost/lockfree/queue.hpp:87:5: error: static assertion failed : (boost::has_trivial_destructor::value) BOOST_STATIC_ASSERT((boost::has_trivial_destructor::value)); ^ /usr/local/include/boost/lockfree/queue.hpp:91:5: error: static assertion failed : (boost::has_trivial_assign::value) BOOST_STATIC_ASSERT((boost::has_trivial_assign::value)); ^ In file included from /usr/local/include/boost/lockfree/queue.hpp:21:0, from /home/ubuntu/Project/src/main.cpp:5: /usr/local/include/boost/lockfree/detail/copy_payload.hpp: In instantiation of ‘ static void boost::lockfree::detail::copy_constructible_and_copyable::copy(T&, U &) [with T = std::basic_string; U = int]’: /usr/local/include/boost/lockfree/detail/copy_payload.hpp:49:25: required from ‘void boost::lockfree::detail::copy_payload(T&, U&) [with T = std::basic_string ; U = int]’ /usr/local/include/boost/lockfree/queue.hpp:402:61: required from ‘bool boost: :lockfree::queue::pop(U&) [with U = int; T = std::basic_string; A0 = boost::parameter::void_; A1 = boost::parameter::void_; A2 = boost::par ameter::void_]’ /home/ubuntu/Project/src/main.cpp:21:24: required from here /usr/local/include/boost/lockfree/detail/copy_payload.hpp:38:11: error: invalid cast from type ‘std::basic_string’ to type ‘int’ u = U(t);

1

1 Answers

2
votes

You need to declare, but not define, your variables in global.h:

extern boost::lockfree::queue<int> q;
extern std::atomic<int> sum;

Then you need to define them in a separate file, global.cpp:

boost::lockfree::queue<int> q{100};
std::atomic<int> sum{0};

I think this should fix your issue. For details, see How do I use extern to share variables between source files?


As for the second part, asking why you can't make a lock-free queue of strings, well, that is answered by the error message: has_trivial_destructor is false for std::string, because it's a dynamically-sized string which allocates memory. You won't be able to use it in this sort of lock-free queue. You can try using a fixed-size string class instead, or std::array<char, N>.