Handling access to shared resources

Discussion in 'C++' started by Angus, May 10, 2009.

  1. Angus

    Angus Guest

    Hello

    I am having a problem with access to a shared std::list. The list is
    accessed via different threads and I use a mutex lock/unlock to ensure
    that only one process can work on the list at any one time. The
    trouble is the lock and unlock is scattered through the code. I am
    having problems where I do a lock but there is no unlock and the code
    gets stuck. It is quite tricky to debug of course.

    Does anyone have any tips on how to handle this problem. Should I use
    some global/singleton accessor function to access the list? But I do
    need to perhaps edit/delete/add to the list. so how best to handle?

    Angus
    Angus, May 10, 2009
    #1
    1. Advertising

  2. Angus

    SG Guest

    On 10 Mai, 08:48, Angus <> wrote:
    > [...] accessed via different threads and I use a mutex lock/unlock
    > to ensure that only one process can work on the list at any one
    > time.  The trouble is the lock and unlock is scattered through the
    > code.  I am having problems where I do a lock but there is no unlock
    > and the code gets stuck.  It is quite tricky to debug of course.
    >
    > Does anyone have any tips on how to handle this problem. Should I use
    > some global/singleton accessor function to access the list? But I do
    > need to perhaps edit/delete/add to the list. so how best to handle?


    You should make use of RAII for the locks. If you're using a C API for
    threads you may want to write your own "lock" class that can be used
    like this:

    void foo() {
    lock l (&mutex);
    // do something
    } // automatically unlock mutex in destructor of 'l'

    This should be the preferred method for locking/unlocking mutexes.
    Something like this is supported by the Boost.Threads library and will
    be supported by the next C++ standard library.

    Cheers!
    SG
    SG, May 10, 2009
    #2
    1. Advertising

  3. Angus

    Jerry Coffin Guest

    In article <f477a125-df51-43e0-86d0-
    >,
    says...
    > Hello
    >
    > I am having a problem with access to a shared std::list. The list is
    > accessed via different threads and I use a mutex lock/unlock to ensure
    > that only one process can work on the list at any one time. The
    > trouble is the lock and unlock is scattered through the code. I am
    > having problems where I do a lock but there is no unlock and the code
    > gets stuck. It is quite tricky to debug of course.
    >
    > Does anyone have any tips on how to handle this problem. Should I use
    > some global/singleton accessor function to access the list? But I do
    > need to perhaps edit/delete/add to the list. so how best to handle?


    Write a class that supports the actual operations you care about, and
    implement the atomicity inside of those individual operations. At least
    for adding and deleting, this can be pretty simple:


    class storage {
    std::list<whatever> list;
    MUTEX m;
    public:
    void add(whatever const &a) {
    acquire(m);
    list.insert(a);
    }

    void delete(whatever const &a) {
    acquire(m);
    std::list<whatever>::iterator pos;
    pos = list.find(a);
    list.remove(pos);
    }
    };

    It's harder to make suggestions about editing. Just for example, without
    knowing more about what you're doing, it's impossible to guess whether
    you need in-place editing, or whether it's reasonable to remove one
    value and insert a new one.

    Though it's necessarily all that directly responsive to your question,
    I'd also note that IME, std::list (and linked lists in general) are only
    rarely a good choice of data structure. There are _usually_ better
    choices. When you need atomic operations, that percentage goes up quite
    a bit further still. The major advantage of a linked list is being able
    to keep accessors (pointers, iterators, etc.) to individual items in the
    list, but those are often quite difficult to reconcile with atomic
    operations.

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
    Jerry Coffin, May 10, 2009
    #3
  4. Angus

    James Kanze Guest

    On May 10, 7:03 pm, Jerry Coffin <> wrote:
    > In article <f477a125-df51-43e0-86d0-
    > >,
    > says...


    > > I am having a problem with access to a shared std::list.
    > > The list is accessed via different threads and I use a mutex
    > > lock/unlock to ensure that only one process can work on the
    > > list at any one time. The trouble is the lock and unlock is
    > > scattered through the code. I am having problems where I do
    > > a lock but there is no unlock and the code gets stuck. It
    > > is quite tricky to debug of course.


    > > Does anyone have any tips on how to handle this problem.
    > > Should I use some global/singleton accessor function to
    > > access the list? But I do need to perhaps edit/delete/add
    > > to the list. so how best to handle?


    > Write a class that supports the actual operations you care
    > about, and implement the atomicity inside of those individual
    > operations. At least for adding and deleting, this can be
    > pretty simple:


    > class storage {
    > std::list<whatever> list;
    > MUTEX m;
    > public:
    > void add(whatever const &a) {
    > acquire(m);
    > list.insert(a);
    > }


    > void delete(whatever const &a) {
    > acquire(m);
    > std::list<whatever>::iterator pos;
    > pos = list.find(a);
    > list.remove(pos);
    > }
    > };


    I suspect that this example is incomplete. It's not clear what
    "acquire(m)" does, but if it simply acquires the lock (as it's
    name suggests), then you're missing the releases. And of
    course, since you can also exit the sequence because of an
    exception (at least in the case of add), you have to ensure that
    it is called then as well---the classical scoped lock pattern
    should definitely be used.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, May 11, 2009
    #4
  5. Angus

    KjellKod Guest

    I agree with "SG", use RAII to solve this.
    Check for more example out Andrei Alexandrescu example of LockingPtr
    at the following Dr.Dobbs article
    http://www.ddj.com/cpp/184403766

    Regards
    / Kjell
    KjellKod, May 11, 2009
    #5
  6. Angus

    SG Guest

    On 11 Mai, 14:32, KjellKod <> wrote:
    > I agree with "SG", use RAII to solve this.
    > Check for more example out Andrei Alexandrescu  example of LockingPtr
    > at the following Dr.Dobbs articlehttp://www.ddj.com/cpp/184403766


    Hmm... this article is 8 years old and covers "volatile" in a way
    that's not in line with what Herb Sutter has to say on this topic [1]
    ("volatile" isn't about multithreading. It's about funky memory areas
    like memory-mapped devices). His "volatile type safety hack" for
    preventing access without locking is an interesting idea, though.

    [1] http://www.ddj.com/hpc-high-performance-computing/212701484

    Cheers!
    SG
    SG, May 11, 2009
    #6
  7. Angus

    Jerry Coffin Guest

    In article <32508b1b-6443-4ca4-98e2-0eafce42d935
    @z19g2000vbz.googlegroups.com>, says...
    > On May 10, 7:03 pm, Jerry Coffin <> wrote:
    > > In article <f477a125-df51-43e0-86d0-
    > > >,
    > > says...

    >
    > > > I am having a problem with access to a shared std::list.
    > > > The list is accessed via different threads and I use a mutex
    > > > lock/unlock to ensure that only one process can work on the
    > > > list at any one time. The trouble is the lock and unlock is
    > > > scattered through the code. I am having problems where I do
    > > > a lock but there is no unlock and the code gets stuck. It
    > > > is quite tricky to debug of course.

    >
    > > > Does anyone have any tips on how to handle this problem.
    > > > Should I use some global/singleton accessor function to
    > > > access the list? But I do need to perhaps edit/delete/add
    > > > to the list. so how best to handle?

    >
    > > Write a class that supports the actual operations you care
    > > about, and implement the atomicity inside of those individual
    > > operations. At least for adding and deleting, this can be
    > > pretty simple:

    >
    > > class storage {
    > > std::list<whatever> list;
    > > MUTEX m;
    > > public:
    > > void add(whatever const &a) {
    > > acquire(m);
    > > list.insert(a);
    > > }

    >
    > > void delete(whatever const &a) {
    > > acquire(m);
    > > std::list<whatever>::iterator pos;
    > > pos = list.find(a);
    > > list.remove(pos);
    > > }
    > > };

    >
    > I suspect that this example is incomplete. It's not clear what
    > "acquire(m)" does, but if it simply acquires the lock (as it's
    > name suggests), then you're missing the releases. And of
    > course, since you can also exit the sequence because of an
    > exception (at least in the case of add), you have to ensure that
    > it is called then as well---the classical scoped lock pattern
    > should definitely be used.


    Sorry -- I should have added a comment that this was really pseudo-code,
    not intended to be fed to a compiler as-is.

    The intent, however, was that the 'acquire' be a scoped lock -- it might
    not be the best name for it, but given the nature of C++, (and the way I
    program) using a lock that wasn't based on RAII is something that would
    hardly even occur to me anymore...

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
    Jerry Coffin, May 11, 2009
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ed J

    global shared resources

    Ed J, Jan 20, 2005, in forum: VHDL
    Replies:
    6
    Views:
    1,990
    Charles Bailey
    Jan 22, 2005
  2. Abhishek Srivastava

    ASP.NET Worker processes and shared resources

    Abhishek Srivastava, Jan 28, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    354
    Abhishek Srivastava
    Jan 28, 2004
  3. Russell E. Owen
    Replies:
    0
    Views:
    701
    Russell E. Owen
    Sep 8, 2006
  4. Maciej

    Pooling shared resources

    Maciej, Aug 10, 2007, in forum: Java
    Replies:
    0
    Views:
    270
    Maciej
    Aug 10, 2007
  5. Jonathan Wood

    Need Authorization to Shared Resources

    Jonathan Wood, Nov 13, 2007, in forum: ASP .Net
    Replies:
    3
    Views:
    348
    Scott Roberts
    Nov 15, 2007
Loading...

Share This Page