possibly ot: thread suspension

Discussion in 'C++' started by Chris Forone, May 12, 2008.

  1. Chris Forone

    Chris Forone Guest

    hello group,

    how does a thread suspend itself? is a volatile bool enough, that is
    checked after each loop?

    thanx a lot & hand, chris
     
    Chris Forone, May 12, 2008
    #1
    1. Advertising

  2. Chris Forone

    James Kanze Guest

    On 12 mai, 09:15, Chris Forone <> wrote:

    > how does a thread suspend itself? is a volatile bool enough,
    > that is checked after each loop?


    It calls the appropriate system function, depending on the
    system. You'll have to ask in a group appropriate for whatever
    system you're using. (In general, though, volatile is neither
    necessary nor sufficient.)

    --
    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 12, 2008
    #2
    1. Advertising

  3. Chris Forone wrote:
    > hello group,
    >
    > how does a thread suspend itself? is a volatile bool enough, that is
    > checked after each loop?


    This is OT but not for long.

    The standard i/f for thread "suspension" will probably be "condition
    variables" IIRC.
     
    Gianni Mariani, May 12, 2008
    #3
  4. On May 12, 9:15 am, Chris Forone <> wrote:

    > how does a thread suspend itself? is a volatile bool enough, that is
    > checked after each loop?


    In contrast to Java, the volatile is not introduced for the
    concurrency issues in C++ and the volatile keyword has the only effect
    on compiler optimisations. Once you declared a variable volatile, the
    compiler will refrain from certain optimisations. That is all. In C++,
    the volatile keyword does not include atomic access as it does for
    simple types in Java.

    Now about the suspend issue: If there are concurrent threads of
    computation going on and these threads share some variables, from the
    perspective of one thread, those shared variables change values non-
    deterministically. Therefore, whenever a thread inspects such a
    variable and expects a certain state from that variable in order to do
    some further computation, it must not just check it and do something
    else if it does not apply. Rather the thread of computation should
    wait for that state of condition to apply. It could do busy wait on it
    as well, and if it were the only thread assigned to that physical
    processor, it could certainly do that. In most cases one physical
    processor carries out a number of threads of computation in an
    overlapping manner. So, the run-time system rather suspends the thread
    that is waiting for a certain state of condition on a shared variable.

    There is a background for the necessity of waiting: If the variable is
    maintained exclusively by a single thread of computation and that
    thread checks that variable, the check result is either false or true
    but once false it will always be false and once true it will always be
    true. It is because the variable can be changed by that thread only
    and that thread can have a chance to change it only if it proceeds.
    The situation is different in case of the shared variables: once false
    it might be true in the next moment due to a concurrent operation by
    an other thread of computation.

    In high level language you could just state the condition and the run-
    time system arranges for the suspension if necessary. If C++ were a
    high level concurrent language, you could state something like this:

    shared class BoundedBuffer {
    std::dequeue<int> b;
    public:
    int get() {
    when (!b.empty()) {
    return b.pop_front();
    }
    }
    ...
    };

    Note that the `shared' declaration denotes a critical resource, which
    is protected against simultaneous access. The `when' statement
    specifies in what condition the computation can proceed with the
    critical action. A possible suspension is arranged automatically.

    In contrast, if you work with low level libraries in C++, you have to
    arrange about delaying the operation yourself. In most libraries there
    is a so-called condition variable for this but you have to care about
    the mutual exclusion as well:

    class BoundedBuffer {
    std::dequeue<int> b;
    pthread_cond_t empty;
    pthread_cond_t full;
    pthread_mutex_t guard;
    public:
    int get() {
    int ret;
    pthread_mutex_lock(&guard);
    while (b.empty()) {
    pthread_cond_wait(&full, &guard);
    }
    ret = b.pop_front();
    pthread_cond_signal(&empty);
    pthread_mutex_unlock(&guard);
    return ret;
    }
    ...
    };

    Now you have suspended the thread in case there is no element in the
    buffer. The thread would normally be awaken later on by a signal sent
    from a corresponding put operation indicating that the buffer has
    elements to consume.

    If you want to check the return values of the library operations, your
    code will be even more complex.

    Best Regards,
    Szabolcs
     
    Szabolcs Ferenczi, May 12, 2008
    #4
  5. Chris Forone

    James Kanze Guest

    On May 13, 1:29 am, "Chris Thomasson" <> wrote:
    > "Szabolcs Ferenczi" <> wrote in message


    > news:...
    > On May 12, 9:15 am, Chris Forone <> wrote:


    > > how does a thread suspend itself? is a volatile bool enough,
    > > that is checked after each loop?


    > [...]


    > > If you want to check the return values of the library operations


    > You must check the return values of pthread calls. IMVHO,
    > applications that fail to at least check status of pthread
    > calls are crap.


    I more or less agree, but... What do you do if
    pthread_mutex_lock() fails? In many cases, the only possible
    cause of failure will be a programming error elsewhere, or
    insufficient resources. In both cases, most of the time, about
    all you can reasonably do is abort with an error message.

    (You definitely do have to consider the case, of course. If
    pthread_mutex_lock() returns with an error, you do NOT have the
    lock.)

    > > your code will be even more complex.


    > Why? You can wrap the raw API calls.


    Generally, you should have anything at that low a level wrapped
    in a class anyway.

    --
    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 13, 2008
    #5
  6. Chris Forone

    James Kanze Guest

    On May 13, 10:10 pm, "Chris Thomasson" <> wrote:
    > "James Kanze" <> wrote in message
    >
    > news:...
    > On May 13, 1:29 am, "Chris Thomasson" <> wrote:
    >
    >
    >
    > > > "Szabolcs Ferenczi" <> wrote in message
    > > >news:...
    > > > On May 12, 9:15 am, Chris Forone <> wrote:
    > > > > how does a thread suspend itself? is a volatile bool enough,
    > > > > that is checked after each loop?
    > > > [...]
    > > > > If you want to check the return values of the library operations
    > > > You must check the return values of pthread calls. IMVHO,
    > > > applications that fail to at least check status of pthread
    > > > calls are crap.

    > > I more or less agree, but... What do you do if
    > > pthread_mutex_lock() fails? In many cases, the only possible
    > > cause of failure will be a programming error elsewhere, or
    > > insufficient resources. In both cases, most of the time, about
    > > all you can reasonably do is abort with an error message.
    > > (You definitely do have to consider the case, of course. If
    > > pthread_mutex_lock() returns with an error, you do NOT have the
    > > lock.)

    >
    > I tend to decorate the lock procedure with throw() and just call
    > std::unexpected() when shi% hits the fan. Although, one could use
    > exceptions... Which brief pseudo-code sketch do you like better:
    >
    > class mutex_with_exceptions {
    > pthread_mutex_t m_mtx;
    >
    > [...];
    >
    > public:
    > struct error {
    > struct base {};
    >
    > struct lock {
    > struct base : public error::base {};
    > struct invalid : public lock::base {};
    > struct priority_violation : pubilc lock::invalid {};
    > struct deadlock : public lock::base {};
    > struct max_recursion : public lock::base {};
    >
    > static void raise_status(int const status) {
    > switch (status) {
    > case EINVAL:
    > throw priority_violation();
    > case EAGAIN:
    > throw max_recursion();
    > case EDEADLK:
    > throw deadlock();
    > default:
    > assert(false);
    > std::unexpected();
    > }
    > }
    > };
    >
    > struct unlock {
    > struct base : public error::base {};
    > struct not_owner : public unlock::base {};
    >
    > static void raise_status(int const status) {
    > switch (status) {
    > case EPERM:
    > throw not_owner();
    > default:
    > assert(false);
    > std::unexpected();
    > }
    > }
    > };
    > };
    >
    > public:
    > void lock() {
    > int const status = pthread_mutex_lock(&m_mtx);
    > if (status) {
    > error::lock::raise_status(status);
    > }
    > }
    >
    > void unlock() {
    > int const status = pthread_mutex_unlock(&m_mtx);
    > if (status) {
    > error::unlock::raise_status(status);
    > }
    > }
    >
    > };
    >
    > -- or --
    >
    > class mutex {
    > pthread_mutex_t m_mtx;
    >
    > [...];
    >
    > public:
    > void lock() throw() {
    > int const status = pthread_mutex_lock(&m_mtx);
    > if (status) {
    > assert(false);
    > std::unexpected();
    > }
    > }
    >
    > void unlock() throw() {
    > int const status = pthread_mutex_unlock(&m_mtx);
    > if (status) {
    > assert(false);
    > std::unexpected();
    > }
    > }
    >
    > };
    >
    > ?
    >
    > > > > your code will be even more complex.
    > > > Why? You can wrap the raw API calls.

    > > Generally, you should have anything at that low a level wrapped
    > > in a class anyway.

    >
    > Indeed!
     
    James Kanze, May 14, 2008
    #6
  7. Chris Forone

    Chris Forone Guest

    Chris Thomasson schrieb:
    > "Chris Forone" <> wrote in message
    > news:g08qpt$ct0$...
    >> hello group,
    >>
    >> how does a thread suspend itself? is a volatile bool enough, that is
    >> checked after each loop?

    >
    > What is the thread suspending itself for? What do you want it to wait on?

    sorry for the delay,

    the thread has an endless working-function that does something and after
    this it sleeps for a calculatet period of time. i want suspend the
    thread from another thread, BUT suspension should only occur at the end
    of the endless loop (after the sleep & before the new activity).

    have mingw & win32
    (http://msdn.microsoft.com/en-us/library/ms686345(VS.85).aspx)

    thanks a lot & hand, chris
     
    Chris Forone, May 15, 2008
    #7
  8. Chris Forone

    Chris Forone Guest

    > Best Regards,
    > Szabolcs


    thanks a lot!!! chris
     
    Chris Forone, May 15, 2008
    #8
    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. Brett
    Replies:
    0
    Views:
    558
    Brett
    Dec 19, 2003
  2. dan byers
    Replies:
    1
    Views:
    624
    Hans =?iso-8859-1?Q?J=F8rgen?= Jakobsen
    Mar 6, 2004
  3. Edward
    Replies:
    7
    Views:
    1,443
    Edward
    Jun 11, 2004
  4. Thomas Carter

    Temporary program suspension

    Thomas Carter, Feb 21, 2005, in forum: C Programming
    Replies:
    12
    Views:
    582
    Richard Bos
    Feb 23, 2005
  5. Eric Wong
    Replies:
    0
    Views:
    103
    Eric Wong
    Apr 22, 2011
Loading...

Share This Page