Boost logo

Boost :

Subject: [boost] [thread] basic mutex problem
From: Greg Rubino (bibil.thaysose_at_[hidden])
Date: 2011-08-12 11:59:32


Hi Boost.Thread maintainer(s)/expert(s)/user(s) like me,

I'm having an issue with boost::mutex. I'm not really an expert in
concurrency, and there's something wrong with my thread_db library, so
I'm having some trouble debugging (for now). I tend to think it's
something in my code, but I thought maybe someone on the list would
take a look at it. The code is pretty minimal, but let me know if I
should reduce it further. I'm leaving out the #includes, because I'm
pretty sure those are ok:

using namespace std;
using namespace boost::phoenix;
namespace phoenix_args = boost::phoenix::arg_names;
namespace posix_time = boost::posix_time;

boost::mutex g_mutex;

struct random_activity_planner {

  random_activity_planner(vector<activity>& a, posix_time::ptime o)
    : activities(a)
    , origin(o) {}

  void operator()() {

    g_mutex.lock();
    posix_time::ptime start(origin + posix_time::seconds(rand() % 1000));
    posix_time::ptime end(start + posix_time::seconds(rand() % 1000));
    activities.push_back(activity(start, end));
    g_mutex.unlock();

  }

  vector<activity>& activities;
  const posix_time::ptime& origin;

};

int main(int argc, char** argv) {

  if(argc != 2)
    return 1;

  size_t activity_count = boost::lexical_cast<size_t>(argv[1]);
  vector<activity> activities;

  boost::thread_group random_activity_planners;
  posix_time::ptime origin(posix_time::second_clock::universal_time());

  srand(time(NULL));
  for(size_t i = 0; i < activity_count; ++i) {
    random_activity_planners.create_thread(random_activity_planner(activities,
origin));
  }
  random_activity_planners.join_all();

  cout << "all activities: " << endl;
  for_each(activities.begin()
           , activities.end()
           , cout << phoenix_args::_1 << endl);

  vector<activity> schedule;

  greedy_activity_selector(activities.begin()
                           , activities.end()
                           , back_inserter(schedule));

  cout << "scheduled activities: " << endl;
  for_each(schedule.begin()
           , schedule.end()
           , cout << phoenix_args::_1 << endl);

  return 0;

}
[END]

The problem is that the last "activity" is not being pushed onto the
shared vector in the . I'm sure there are some stylistic problems
with the code, but its purpose is just to demonstrate an algorithm.

At the following for_each() call:

  for_each(activities.begin()
           , activities.end()
           , cout << phoenix_args::_1 << endl);

I find out, via a gregorian::bad_year exception, that the final
activity has not been initialized. I have omitted the definition for
activity, but it's pretty simple. It has only one member (a
posix_time::duration that defaults to neg_infin => pos_infin ), which
is why I suspect that the final call to
random_activity_selector::operator() is not completing before the
for_each() call that succeeds it in the source. I thought that
join_all() would prevent this from happening. Is there something
wrong with my code? I left some stuff out, because I didn't want to
inundate the reader with irrelevant details, so please let me know if
I left out anything crucial. Also, I am aware that I don't need to be
using threads here, but I am, and I don't understand why it's not
working.

Thanks!

Greg


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk