Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #103862

Re: Memory not updating in thread as expected

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>

Show all headers | View raw


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


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