Showing posts with label Boost. Show all posts
Showing posts with label Boost. Show all posts

Sunday, July 12, 2015

Example Boost MultiI ndex Container

Here is a quick example to get to you started with boost::multi_index_container. Multi_index containers enables defining containers maintaining one or more indices with different sorting and access semantics.
Here is a sample program to get you started:


#include <boost/multi_index_container.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/hashed_index.hpp>

#include <iostream>

class CartItem{

public:

 int64_t cartItemId;
 int barcode;
 char symbol[10];        
 int64_t validityDate;     
 float price;

};


struct CartItemByCartItemIdIndexTag{};
struct CartItemByBarcodeIndexTag{};

typedef boost::multi_index_container<
 CartItem,
 boost::multi_index::indexed_by<
  boost::multi_index::hashed_unique<
   boost::multi_index::tag<CartItemByCartItemIdIndexTag>,
   boost::multi_index::member<CartItem, int64_t, &CartItem::cartItemId>
  >,
  boost::multi_index::hashed_unique<
   boost::multi_index::tag<CartItemByBarcodeIndexTag>,
   boost::multi_index::member<CartItem, int, &CartItem::barcode>  
  >
 >
> CartItemMapContainer;


typedef CartItemMapContainer::index<CartItemByCartItemIdIndexTag>::type CartItemByCartItemIdIndex;
typedef CartItemMapContainer::index<CartItemByBarcodeIndexTag>::type CartItemByBarcodeIndex;

//Global Variable
CartItemMapContainer  itemmultiIndexContainer;

void insertItem(int64_t cartItemId, int barcode){


 CartItem c;
 c.cartItemId = cartItemId;
 c.barcode = barcode;

 //Insert operation
 CartItemByCartItemIdIndex& index = itemmultiIndexContainer.get<CartItemByCartItemIdIndexTag>();

 if(!index.insert(c).second){
  std::cout << "Error inserting item";

 }
 else
  std::cout << "Insert successful\n";

}

void searchByItemId(int64_t cartItemId){

 CartItem d;
 //Find Operation by CartItemId
 CartItemByCartItemIdIndex& idx = itemmultiIndexContainer.get<CartItemByCartItemIdIndexTag>();
 CartItemByCartItemIdIndex::iterator itrb = idx.find(cartItemId);

 if(itrb == idx.end()){
  std::cout << "Look up By CartItemId failed";
  return;
 }
 else
  d = (*itrb);

 std::cout << "CartItemId:" << d.cartItemId << ", Barcode:" << d.barcode << std::endl;
}

void searchByBarcode(int barcode){

 CartItem e;
 CartItemByBarcodeIndex& indexByBarCode = itemmultiIndexContainer.get<CartItemByBarcodeIndexTag>();
 CartItemByBarcodeIndex::iterator itr = indexByBarCode.find(barcode);

 if(itr == indexByBarCode.end()){
  std::cout << "look up By BarCode failed";
  return;
 }
 else
  e = *itr;

 std::cout << "CartItemId:" << e.cartItemId << ", Barcode:" << e.barcode << std::endl;

}

int main(){

 insertItem(1,2);
 insertItem(2,4);
 insertItem(3,6);
 searchByItemId(1);
 searchByBarcode(6);


 return 0;

}

Sunday, May 31, 2015

Boost Mutex scoped_lock example

Here is a quick example showing how mutex helps in doing a synchronous access on shared resource. We are using boost::mutex::scoped_lock here, which ensures that the ownership of the mutex object is relinquished even in case the code following the lock throws an exception, thus preventing possible thread deadlocks.

#include <boost/thread/thread.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/bind.hpp>
#include <iostream>

//Compile using : g++ program.cpp -lboost_thread

boost::mutex io_mutex;

void count(int id)
{
  for (int i = 0; i < 5; ++i)
  {
    boost::mutex::scoped_lock lock(io_mutex);
    std::cout << id << ": " << i << std::endl;
  }
}


void countWithoutMutex(int id)
{
  for (int i = 0; i < 5; ++i)
  {
    std::cout << id << ": " << i << std::endl;
  }
}


int main(int argc, char* argv[])
{
std::cout << "The wrong way\n";
  boost::thread thrd1(
    boost::bind(&countWithoutMutex, 1));
  boost::thread thrd2(
    boost::bind(&countWithoutMutex, 2));
  thrd1.join();
  thrd2.join();
std::cout << "Now the right way\n";
   boost::thread thrd3(
    boost::bind(&count, 3));
  boost::thread thrd4(
    boost::bind(&count, 4));
  thrd3.join();
  thrd4.join();
  

  return 0;
}
Output:

The wrong way
2: 01: 0
1: 1
1: 2
1: 3
1: 4

2: 1
2: 22
: 3
2: 4
Now the right way
3: 0
3: 1
3: 2
3: 3
3: 4
4: 0
4: 1
4: 2
4: 3
4: 4

Sunday, August 31, 2014

[Explained] pthread_mutex_destroy failed


If you ever run into the following error while running a multithreaded application in C++ application which makes use of mutex's for synchronization



networkDataShareSyncApp: /usr/local/include/boost/thread/pthread/mutex.hpp:47: 
boost::mutex::~mutex(): Assertion `!pthread_mutex_destroy(&m)' failed.
Aborted (core dumped)


gdb detailed stack trace for the same problem:

(gdb) bt
#0  0x00000034594328a5 in raise () from /lib64/libc.so.6
#1  0x0000003459434085 in abort () from /lib64/libc.so.6
#2  0x000000345942ba1e in __assert_fail_base () from /lib64/libc.so.6
#3  0x000000345942bae0 in __assert_fail () from /lib64/libc.so.6
#4  0x0000000000404391 in boost::mutex::~mutex (this=0x608e80, 
__in_chrg=<value optimized out>) at 
/usr/local/include/boost/thread/pthread/mutex.hpp:47
#5  0x0000003459435da2 in exit () from /lib64/libc.so.6
#6  0x000000345941ece4 in __libc_start_main () from /lib64/libc.so.6
#7  0x00000000004036a9 in _start ()
(gdb) 


Then the problem might be:
a) Either your main() thread/program is exiting without joining the threads, and one of the threads is still using/referencing to the mutex variable
b) You are trying to destroy/delete the mutex explicitly from one of your thread, while it is still being referenced/used from another thread. Attempting to destroy a locked mutex results in undefined behavior.

Source : https://linux.die.net/man/3/pthread_mutex_destroy.
Read more about an interesting discussion here.


Sunday, June 17, 2012

[Resolved] Boost :: undefined reference to `boost::system::system_category()'

Ran into to a small compilation error today.
while compiling a program with the  boost::asio namespace, i got the following error:

/tmp/ccYz5ppN.o: In function `__static_initialization_and_destruction_0(int, int)':
CancelTimer.cpp:(.text+0x21a): undefined reference to `boost::system::generic_category()'
CancelTimer.cpp:(.text+0x226): undefined reference to `boost::system::generic_category()'
CancelTimer.cpp:(.text+0x232): undefined reference to `boost::system::system_category()'
/tmp/ccYz5ppN.o: In function `boost::system::error_code::error_code()':
CancelTimer.cpp:(.text._ZN5boost6system10error_codeC2Ev[_ZN5boost6system10error_codeC5Ev]+0x17): undefined reference to `boost::system::system_category()'

Well it turns out the boost::system::error_code::error_code() depends on the boost_system library.

So compiling with the -lboost_system linker flag to locate the symbols in library libboost_system.so solved the problem for me.
 

[C#] Mutliple Concurrent Producers and Consumers pattern for a Task Queue

If you are in need of a basic concurrent Producers consumers pattern to be used in your application, here is a sample C# program to refer to...