-2

multiple threads accessing same function to check reachability if any one thread completed and got reachable status then exit from main by priting the status dont wait for other threads to complete. in the below code i have use while() loop inside main please suggest me is there any other way without using while loop in main

    #include<iostream>
    #include<thread>
    #include<unistd.h>
    #include<string>
    #include<string.h>
    #include<vector>
    
    
    using namespace std;
    
    enum sraChkReturnCode
    {
        Server_Chk_Success,    // server check is success
        Server_Not_Reachable,  // Server is not reachable
        Server_Reachable,      // server is reachable
    };
    
    bool  g_isLocalNetwork = false;
    int g_completed_thread_cnt=0;
    
    int checkReachability(std::string strServer)//this function is timetaking function
    {
        sleep(2);
        if(strServer=="WHATSAPP")
        return Server_Reachable;
        else
        return Server_Not_Reachable;
    }
    
    void ThreadFunction(std::string strServer)
    {     
           int  Local= Server_Not_Reachable;
           
           cout<<"Thread function starts\n";
             Local = checkReachability(strServer);
             if(Local==Server_Reachable)
             {
                 g_isLocalNetwork = true;
             }
       ++g_completed_thread_cnt;
       cout<<"\ncompleted_thread_cnt="<<g_completed_thread_cnt<<endl;
       
    }
    
    int main()
    {
       vector<string>vecServers{"INSTAGRAM","FACEBOOK","TWITTER","YOUTUBE","WHATSAPP","GOOGLE","EDGE","TELEGRAM","FIREFOX"};
       int vsize=vecServers.size();
          for (auto& strServer: vecServers)
          {
             std::thread th(ThreadFunction, strServer);
             th.detach();
          }
        
        while(g_isLocalNetwork ==false && g_completed_thread_cnt!=vsize)
        {
            ;
        }
        cout<<"vsize="<<vsize<<" and g_completed_thread_cnt="<<g_completed_thread_cnt<<endl;
        if (g_isLocalNetwork == true) 
        {
            cout<<"\nConnection reachable\n";
        } 
        else 
        {
            cout<<"\nConnection not reachable\n";
        }
    }
        
    
        
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Why `.detach()`? – Armali Jul 26 '21 at 09:41
  • All threads independently run background, i have written while loop inside the main so that it will wait untill any thread successfully completes. if i use join then i need to wait for all threads to complete, so thats why i have used detach. – user16526881 Jul 26 '21 at 10:59
  • I am just trying to write a code on multiple threads doing same job if any one thread is completed (with status=true) then print the result and exit (dont wait in main), please suggest me if there is any better way. – user16526881 Jul 26 '21 at 11:03
  • iam just trying to write a mechanism which fetch result/status quickly. – user16526881 Jul 26 '21 at 11:20
  • This program exhibits undefined behavior by way of a data race. It reads and modifies non-atomic objects concurrently with no synchronization. – Igor Tandetnik Jul 26 '21 at 15:05
  • You can use `std::condition_variable` to avoid the busy loop. `main` would wait on it, worker threads would notify it when finished. – Igor Tandetnik Jul 26 '21 at 15:08
  • i forgot to metion that g_isLocalNetwork and g_completed_thread_cnt atomic variables (assume) – user16526881 Jul 26 '21 at 15:50
  • Can you please rewrite the code how we can do with the help of condition_variable ? – user16526881 Jul 26 '21 at 15:52
  • NOTE:if one thread is finished (if connection established) then i dont want to wait in main for other threads to finish. i just want to print the status thats it. – user16526881 Jul 26 '21 at 16:42

1 Answers1

0

Can you please rewrite the code how we can do with the help of condition_variable ?

Here's how I'd implement Igor Tandetnik's good advice to use std::condition_variable; at file scope

#include <mutex>
#include <condition_variable>
mutex m;
condition_variable cv;

- then change ++g_completed_thread_cnt; to

        { lock_guard<mutex> lk(m); ++g_completed_thread_cnt; }
        cv.notify_one();

and change

        while(g_isLocalNetwork ==false && g_completed_thread_cnt!=vsize)
        {
            ;
        }
        cout<<"vsize="<<vsize<<" and g_completed_thread_cnt="<<g_completed_thread_cnt<<endl;

to

        unique_lock<mutex> lk(m);
        cv.wait(lk, [vsize]{ return g_isLocalNetwork || g_completed_thread_cnt==vsize; });
        cout<<"vsize="<<vsize<<" and g_completed_thread_cnt="<<g_completed_thread_cnt<<endl;
        lk.unlock();
Armali
  • 18,255
  • 14
  • 57
  • 171
  • you are using same mutex "m" in thread function and same in main() also is it ok? – user16526881 Jul 27 '21 at 09:43
  • Yes, _the same mutex_ is required, see [`std::condition_variable`](https://en.cppreference.com/w/cpp/thread/condition_variable). – Armali Jul 27 '21 at 16:05
  • suppose second thread is reachble and notified to main and inside main wait got successfull and exited ,now after cv.wait() before exiting main, if any other thread called notify() what will happen in this case?. – user16526881 Jul 27 '21 at 16:22
  • As Ceasar puts it in his [answer to What happens to a detached thread when main() exits?](https://stackoverflow.com/a/19744290/2413201), _a modern operating system will clean up all threads created by the process on closing it._ So, on _a modern operating system_ no other thread does anything anymore after main exited. – Armali Jul 27 '21 at 16:51