Get a lock as soon as it appears.

I have two threads trying to block the same one boost::mutex. One of these threads continuously processes some data, and the other periodically displays the current state. The processing thread, in accordance with my intention, very often releases the lock and restores it, so that the display thread can connect to it and acquire it when it needs it. Therefore, obviously, I would like the display thread to acquire a lock the next time it was released by the process thread. However, he does not do this; instead, he waits for a lock and receives it only after many lock cycles from the process.

Please check out the minimal example illustrating my problem:

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

using namespace std;
using namespace boost;

mutex mut;

void process() {
        double start = time(0);
        while(1) {
                unique_lock<mutex> lock(mut);
                this_thread::sleep(posix_time::milliseconds(10));
                std::cout<<".";
                if(time(0)>start+10) break;
        }
}

int main() {

        thread t(process);

        while(!t.timed_join(posix_time::seconds(1))) {
                posix_time::ptime mst1 = posix_time::microsec_clock::local_time();
                cout<<endl<<"attempting to lock"<<endl;
                cout.flush();

                unique_lock<mutex> lock(mut);

                posix_time::ptime mst2 = posix_time::microsec_clock::local_time();
                posix_time::time_duration msdiff = mst2 - mst1;
                cout << std::endl<<"acquired lock in: "<<msdiff.total_milliseconds() << endl;
                cout.flush();
        }

}

Compiled with: g++ mutextest.cpp -lboost_thread -pthread

, :

...................................................................................................
attempting to lock
....................................................................................................................................................................................................................................................................................................................................................................................................................................
acquired lock in: 4243
...................................................................................................
attempting to lock
........................................................................................................
acquired lock in: 1049
...................................................................................................
attempting to lock
........................................................................................................................
acquired lock in: 1211
....................................

, 424 - , .

, , , ?

+5
5

, , FKaria, . , , , , . , , . : ( , //New)

#include <boost/thread.hpp>
#include <boost/thread/condition.hpp>
#include <iostream>

using namespace std;
using namespace boost;

mutex mut;
condition cond;

volatile bool shouldPause = false; //New

void process() {
        double start = time(0);
        while(1) {
                unique_lock<mutex> lock(mut);

                if(shouldPause) cond.wait(mut); //New

                this_thread::sleep(posix_time::milliseconds(10));
                std::cout<<".";
                if(time(0)>start+10) break;
        }
}

int main() {

        thread t(process);

        while(!t.timed_join(posix_time::seconds(1))) {
                posix_time::ptime mst1 = posix_time::microsec_clock::local_time();
                cout<<endl<<"attempting to lock"<<endl;
                cout.flush();
                shouldPause = true; // New
                unique_lock<mutex> lock(mut);

                posix_time::ptime mst2 = posix_time::microsec_clock::local_time();
                posix_time::time_duration msdiff = mst2 - mst1;
                cout << std::endl<<"acquired lock in: "<<msdiff.total_milliseconds() << endl;
                cout.flush();

                shouldPause = false; // New
                cond.notify_all(); // New
        }

}

, :

...................................................................................................
attempting to lock
.
acquired lock in: 9
...................................................................................................
attempting to lock
.
acquired lock in: 8
...................................................................................................
attempting to lock
.
acquired lock in: 9
...................................................................................................
attempting to lock
.
acquired lock in: 8
...................................................................................................
attempting to lock
.
acquired lock in: 9
...................................................................................................
attempting to lock
.
acquired lock in: 9
...................................................................................................
attempting to lock
.
acquired lock in: 9
...................................................................................................
attempting to lock
.
acquired lock in: 9
...................................................................................................
attempting to lock
.
acquired lock in: 8
...................................................................................................
attempting to lock
.
acquired lock in: 9
..........................
0

, , , . , , ( "" ), , ; . this_thread::yield() ( , , ); , . , ; , .

+4

, , .

boost:: condition_variable. http://www.boost.org/doc/libs/1_53_0/doc/html/thread/synchronization.html

, - GUI, , , - . ( .) , , , " ".

, , , , , .

+1

boost:: condition_variable, wait() notify_one() notify_all(), wait() , . notify_one() notify_all() , .

+1

, - , . . , , - , 2 , ​​ . , /.

( ), , .

, , :

  • - ,
  • , , ,
  • make the lock much finer.

Unfortunately, none of them is problematic.

+1
source

All Articles