asit_dhal
asit_dhal

Reputation: 1269

stl map simultaneous write sample code

I want to simulate the abnormal behavior of stl map in simultaneous write condition. Here I am using a single map and simultaneously inserting data from multiple threads. As we are using only one map object, hence it should not allow. Please go through the following sample code

    #include <iostream>
    #include <map>
    #include <iterator>
    #include <algorithm>

    extern "C"
    {
    #include <pthread.h>
    #include <string.h>
    #include <stdlib.h>
    }

    using namespace std;

//functor to print map
    struct PrintMp
    {
       void operator()(pair<int,int> pr)
       {
          cout<<pr.first<<" => "<<pr.second<<endl;
       }
    };
//thread 1
//inserts continuous no from 0 to 4999    
    void* ins_th1(void *arg)
    {
       map<int, int> *mp = static_cast<map<int, int>* >(arg);
       for(int i =0 ; i<5000; i++)
          mp->insert(pair<int,int>(i, i+1000));

       return NULL;
    }

//thread 1
//inserts continuous no from 0 to 4999    
    void* ins_th2(void *arg)
    {
       map<int, int> *mp = static_cast<map<int,int>* >(arg);
       for(int i=5000; i<10000; i++)
          mp->insert(pair<int, int>(i, i+2000));
       return NULL;
    }


    int main()
    {
       typedef map<int, int> IntMapType;

       IntMapType mp;
       PrintMp MpPrintObj;
       int rc;

       pthread_t th1, th2;
    //thread 1 creation
       rc = pthread_create(&th1, NULL, ins_th1, static_cast<void*>(&mp));
       if ( rc != 0)
       {
          cerr<<strerror(rc)<<"in thread1"<<endl;
          exit(EXIT_FAILURE);
       }
    //thread 2 creation
       rc = pthread_create(&th2, NULL, ins_th2, static_cast<void*>(&mp));
       if(rc!=0)
       {
          cerr<<strerror(rc)<<"in thread2"<<endl;
          exit(EXIT_FAILURE);
       }
    //lets wait for the thread to finish
       rc = pthread_join(th1, NULL);
       if ( rc != 0)
       {
          cerr<<strerror(rc)<<"join failure for thread1"<<endl;
          exit(EXIT_FAILURE);
       }

       rc = pthread_join(th2, NULL);
       if ( rc != 0)
       {
          cerr<<strerror(rc)<<"join failure for thread2"<<endl;
          exit(EXIT_FAILURE);
       }

       cout<<"Map data"<<endl;
    //now print it
       for_each(mp.begin(), mp.end(), MpPrintObj);
       cout<<endl;

       return 0;
    }

But it doesn't work. Can anyone suggest me some approach ?

Upvotes: 0

Views: 182

Answers (2)

asit_dhal
asit_dhal

Reputation: 1269

I tried to implement as you said.

But despite not using any synchronization mechanism, I am getting the perfect result.

Upvotes: 0

jxh
jxh

Reputation: 70402

You are only testing insertion, which may or may not be implemented in a thread safe fashion, for all you know. But, your test is not complete. Allow the threads to write the same key into the map, and you will likely experience an error that would not happen without multiple threads.

   // ins_th1
   for(int i =0 ; i<10000; i++)
      mp->insert(pair<int,int>(i, i+1000));

   // ins_th2
   for(int i=0; i<10000; i++)
      mp->insert(pair<int, int>(i, i+2000));

You should test deletion from the map as well. When I modified your program to populate the map, before launching the threads, and only had the threads remove things from the map, the program live-locked.

   // ins_th1
   for(int i =0 ; i<5000; i++)
      mp->erase(i);

   // ins_th2
   for(int i=5000; i<10000; i++)
      mp->erase(i);

   // near top of main
   for(int i =0 ; i<5000; i++)
      mp.insert(pair<int,int>(i, i+1000));
   for(int i=5000; i<10000; i++)
      mp.insert(pair<int, int>(i, i+2000));
   //... launch threads

Upvotes: 1

Related Questions