possibly ot: thread suspension

C

Chris Forone

hello group,

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

thanx a lot & hand, chris
 
J

James Kanze

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.)
 
G

Gianni Mariani

Chris said:
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.
 
S

Szabolcs Ferenczi

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
 
J

James Kanze

"Szabolcs Ferenczi" <[email protected]> wrote in message
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.)
Why? You can wrap the raw API calls.

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

James Kanze

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();
}
}

};

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

Indeed!
 
C

Chris Forone

Chris said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,008
Latest member
HaroldDark

Latest Threads

Top