Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #103862
| From | Alain Ketterlin <alain@universite-de-strasbourg.fr.invalid> |
|---|---|
| Newsgroups | comp.lang.c |
| Subject | Re: Memory not updating in thread as expected |
| Date | 2017-02-14 10:43 +0100 |
| Organization | Université de Strasbourg |
| Message-ID | <8737fh2jm6.fsf@universite-de-strasbourg.fr.invalid> (permalink) |
| References | <s023ac5gl1bpefvi63upl7tb6iunf0a8mo@4ax.com> <d52fe51a-1f8d-47fe-9283-5f1c13f5a05d@googlegroups.com> <ggg3acdd9s4h3p47f4488mns89opglousv@4ax.com> <o7tb2c$40o$1@dont-email.me> <o7ts13$d40$1@dont-email.me> |
James Kuyper <jameskuyper@verizon.net> writes:
> You sound like you have some idea how to do this kind of thing (which is
> more than I could say about myself). I'd prefer (particularly in this
> newsgroup) sticking strictly to C2011's new threading library, rather
> than making any use of anything Linux-specific. Could you (or anyone
> else who cares to do so) show us the right way to do something like the
> OP's original code?
Here is the setting, as far as I remember: one thread does some work and
then "wakes up" another, that then has other work to do:
work1();
signal ----> wait
work2();
where work2() cannot start before work1() is finished.
You need two main things: one is a (set of) regular variables indicating
the work is done. OP used an array element, I'll use a single boolean
bool ready = false; // init at the start of program
(use whatever is needed to represent the logical conditions: it could be
a set of variables or array elements...)
Then you need synchronization objects: I'll use a condition variable
(and therefore an accompanying mutex):
mtx_t m;
cnd_t c;
The mutex will protect concurrent accesses to "ready", and the condition
variable will provide the signaling mechanism. Both need to be properly
initialized before any use.
Now here is what thread 1 must do:
work1();
mtx_lock(&m);
ready = true;
cnd_signal(&c);
mtx_unlock(&m);
It is not mandatory that cnd_signal() is included inside
mtx_lock()/mtx_unlock() I think (not sure about this---when I learned
condition variables on Solaris the _signal had to be protected).
Now here is what thread 2 must do:
mtx_lock(&m);
while ( ready == false )
cnd_wait(&c,&m);
mtx_unlock(&m);
work2();
In the general case, thread 2 must loop, but here the "while" could be
an "if", because the synchronization is so simple. Anyway, cnd_wait()
avoids the (disastrous) busy-wait the OP used.
Now this works whatever the executions interleaving is.
1) Suppose thread 1 is very fast and completes (i.e., signals) before
thread 2 even reaches the mtx_lock(): in that case, thread 2 will
later lock the mutex, find "ready == true", immediately unlock the
mutex and proceed.
2) Suppose thread 2 is very fast: it will lock the mutex, enter the loop
and block in cnd_wait() until someone signals on c, leaving the mutex
unlocked (yes, cnd_wait() does all this at once). Thread 2 will stay
blocked until thread 1 calls cnd_signal(). At that point, thread 2 is
waken up but waits inside cnd_wait() for the mutex to be unlocked,
which will only happen when thread 1 calls mtx_unlock(). When this
happens thread 2 holds the mutex, and can test its logical condition
("ready == false") again, exit the loop, unlock the mutex, and
proceed.
3) If both threads reach mtx_lock() at about the same time, only one of
them will succeed in mtx_lock(). Which one is the winner determines
on whether we are back to case 1) or 2).
Note that this works only for a single signal-wait cycle. If this cycle
is to be repeated, more complex synchro is needed (essentially, thread2
has to "acknowledge" receipt of the signal, reset the "ready" variable,
etc.)
Note also that the whole thing would be much simpler with a semaphore.
C11 has no semaphores afaik. Using a POSIX semaphore s, the code would
be:
(thread 1)
work1();
sem_post(&s);
(thread 2)
sem_wait(&s);
work2();
> He didn't provide a complete program, or any context for that code, so
> feel free to make reasonable choices about what the context would
> actually look like, without making it excessively complicated. str1[0]
> seems to be being used solely for the purpose of synchronizing
> execution of the two threads, and the rest of the allocated memory is
> not used at all, so feel free to drop the allocated memory entirely,
> and use the most appropriate method to achieve that synchronization.
That's what I did: the "ready" boolean above plays the role of
str1[0] being equal to 50 (or whatever).
> I'm not just asking this on the OP's behalf - I've little experience
> with this kind of code, and none of it recent, and therefore none of
> it using C2011 - so I'd like to see it for myself.
If you have used pthread's library functions, the correspondance is
immediate:
mtx_lock() <-> pthread_mutex_lock()
...
cnd_signal() <-> pthread_cond_signal()
...
-- Alain.
Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
Memory not updating in thread as expected Test <test@.nil.invalid.com> - 2017-02-13 12:46 +0200
Re: Memory not updating in thread as expected m.labanowicz@gmail.com - 2017-02-13 05:18 -0800
Re: Memory not updating in thread as expected Test <test@.nil.invalid.com> - 2017-02-13 16:25 +0200
Re: Memory not updating in thread as expected m.labanowicz@gmail.com - 2017-02-13 10:30 -0800
Re: Memory not updating in thread as expected Jerry Stuckle <jstucklex@attglobal.net> - 2017-02-13 14:30 -0500
Re: Memory not updating in thread as expected m.labanowicz@gmail.com - 2017-02-13 05:46 -0800
Re: Memory not updating in thread as expected Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-02-13 14:30 +0000
Re: Memory not updating in thread as expected "Chris M. Thomasson" <invalid@invalid.invalid> - 2017-02-13 15:13 -0800
Re: Memory not updating in thread as expected Test <test@.nil.invalid.com> - 2017-02-13 16:36 +0200
Re: Memory not updating in thread as expected David Brown <david.brown@hesbynett.no> - 2017-02-13 23:15 +0100
Re: Memory not updating in thread as expected James Kuyper <jameskuyper@verizon.net> - 2017-02-13 22:04 -0500
Re: Memory not updating in thread as expected David Brown <david.brown@hesbynett.no> - 2017-02-14 09:44 +0100
Re: Memory not updating in thread as expected Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-02-14 11:07 +0000
Re: Memory not updating in thread as expected David Brown <david.brown@hesbynett.no> - 2017-02-14 12:46 +0100
Re: Memory not updating in thread as expected Robert Wessel <robertwessel2@yahoo.com> - 2017-02-16 05:12 -0600
Re: Memory not updating in thread as expected David Brown <david.brown@hesbynett.no> - 2017-02-16 12:44 +0100
Re: Memory not updating in thread as expected Alain Ketterlin <alain@universite-de-strasbourg.fr.invalid> - 2017-02-14 15:53 +0100
Re: Memory not updating in thread as expected Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-02-14 15:36 +0000
Re: Memory not updating in thread as expected Alain Ketterlin <alain@universite-de-strasbourg.fr.invalid> - 2017-02-14 17:58 +0100
Re: Memory not updating in thread as expected Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-02-14 17:26 +0000
Re: Memory not updating in thread as expected Alain Ketterlin <alain@universite-de-strasbourg.fr.invalid> - 2017-02-14 10:43 +0100
Re: Memory not updating in thread as expected Robert Wessel <robertwessel2@yahoo.com> - 2017-02-14 03:52 -0600
Re: Memory not updating in thread as expected Alain Ketterlin <alain@universite-de-strasbourg.fr.invalid> - 2017-02-14 11:36 +0100
Re: Memory not updating in thread as expected supercat@casperkitty.com - 2017-02-14 05:31 -0800
Re: Memory not updating in thread as expected Ken Brody <kenbrody@spamcop.net> - 2017-02-13 12:44 -0500
Re: Memory not updating in thread as expected Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2017-02-13 10:58 -0700
Re: Memory not updating in thread as expected "Chris M. Thomasson" <invalid@invalid.invalid> - 2017-02-14 15:13 -0800
Re: Memory not updating in thread as expected "Chris M. Thomasson" <invalid@invalid.invalid> - 2017-02-14 16:37 -0800
csiph-web