0

I'm new to threads.. I'm trying to write a function that would write the pid of the thread to a given vector. When I check the size of the vector at the end of the program, I expect it to be 2, instead of 1.

What is a suggested way to add data to the tmp vector such that tmp is not local to each thread?

#include <iostream>
#include <pthread.h>
#include <vector>

using namespace std;

#define NUM_THREADS     2
vector<pthread_t> tmp;

void *PrintHello(void *threadid)
{
   long tid;
   tid = (long)threadid;
   pthread_t pid = pthread_self();
   tmp.push_back(pid);
   cout << "Hello World! Thread ID, " << tid << " " << pid << endl;
   pthread_exit(NULL);
}

int main ()
{
   int rc;
   int i;
    vector<pthread_t> vectorOfThreads(NUM_THREADS);
    for( i=0; i < NUM_THREADS; i++ ){
      rc = pthread_create(&vectorOfThreads[i], NULL, 
                              PrintHello, (void *)i);

      if (rc){
         cout << "Error:unable to create thread," << rc << endl;
         return 1;
      }
   }

    cout << "size of tmp " << tmp.size() << endl;
   pthread_exit(NULL);
   return 0;
}
tandem
  • 2,040
  • 4
  • 25
  • 52
  • 1
    Concurrent writes to the same global vector from multiple threads should (must) be (mutex) locked. Though, doing this might degrade performance because threads will be serialized by this. (This is communication overhead which makes a parallel algorithm slower than a serial.) The better way is to let threads write their local data which are merged after join. – Scheff's Cat Apr 15 '19 at 10:01
  • Could you maybe give an example of this? or point me to a link that explains this a bit. – tandem Apr 15 '19 at 10:03
  • Another possibility could be to pre-allocate global vector and "assign" each thread the element it may write to. If the outcome isn't read before join no extra mutex might be needed for this. – Scheff's Cat Apr 15 '19 at 10:05
  • 1
    `Could you maybe give an example of this?` search google for pthread_mutex thare are many examples online. You should protect all access to shared variables with a mutex. `pthread_mutex_lock(&mtx); tmp.push_back(pid); pthread_mutex_unlock(&mtx);` etc. If you use C++, why don't you use `std::thread` and `std::mutex`? – KamilCuk Apr 15 '19 at 10:07
  • May be, this example could be of help: [SO: Multi-threading benchmarking issues](https://stackoverflow.com/a/52835213/7478597) where I myself experimented a bit with multi-threading. In this, I used the 2nd hint. – Scheff's Cat Apr 15 '19 at 10:07
  • How should it be done without mutex lock? I can do it with them now – tandem Apr 15 '19 at 10:10
  • That's the problem about MT: You can do any multi-threading with unlocked concurrent read/write accesses to shared variables (bad!) without any compiler error. The program sometimes seems to work sometimes not. Doing MT wrong is often hard to track. The only thing you get: Sometimes you have errors which are hard to explain. – Scheff's Cat Apr 15 '19 at 10:12
  • _How should it be done without mutex lock?_ Pre-allocating storage before starting the threads (e.g. `std::vector::resize(nThreads);`, assigning each thread another element to write to, and don't read the result (in vector) before joining all threads. The `std::vector::push_back()` is an access to the global vector which is not multi-threading safe. That's why this had to be guarded by a mutex but then... (see above). – Scheff's Cat Apr 15 '19 at 10:15
  • Too late for an answer. ;-) However, I made a small sample about what I suggested above. Here it is: [**Live Demo on coliru**](http://coliru.stacked-crooked.com/a/2582cb6563688f9f). However, multi-threading is not trivial. Examples may help but, please, try to find educational sources to learn to do it right. – Scheff's Cat Apr 15 '19 at 10:35
  • thanks for your answer. that did help! I would gladly accept the answer, if given a chance. – tandem Apr 15 '19 at 15:12

0 Answers0