Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I do think your approach with a precedence graph is correct, but the problem statement is a bit unclear, for example, from the graph is looks like <code>B</code> and <code>C</code> can occur in any order, but no indication of this in the original a) and b) sequences.</p> <p>(<strong>EDIT:</strong> it become clear that <code>B</code> and <code>C</code> have to alternate)</p> <p>So, for case a) the following (infinite) sequence is acceptable:</p> <pre><code>ABCD ACBD ABCD ACBD ABCD ACBD ... A&lt;--+ / \ | B&lt;-&gt;C | \ / | D---+ </code></pre> <p><code>A</code> precedes <code>B</code> by program logic and they are in the same thread. Likewise <code>C</code> precedes <code>D</code> for the same reasons. Hence, semaphores are needed to enforce precedence only along the edges <code>A-&gt;C</code>, <code>B-&gt;D</code> and <code>D-&gt;A</code>. The edge between <code>B</code> and <code>C</code> changes direction each cycle, hence we need an additional bit of state, to determine the direction: <code>B-&gt;C</code> or <code>B&lt;-C</code> It can be done with an extra variable, or we can maintain the state implicitly by duplicating the loop bodies, like below:</p> <pre><code>#include &lt;semaphore.h&gt; #include &lt;pthread.h&gt; #include &lt;stdio.h&gt; #define NLOOPS 100000 sem_t s0, s1, s2, s3; void * process_A (void *unused) { int n = NLOOPS; while (n--) { sem_wait (&amp;s0); putchar ('A'); sem_post (&amp;s1); putchar ('B'); sem_post (&amp;s3); sem_post (&amp;s2); sem_wait (&amp;s0); putchar ('A'); sem_post (&amp;s1); sem_wait (&amp;s3); putchar ('B'); sem_post (&amp;s2); } return 0; } void * process_B (void *unused) { int n = NLOOPS; while (n--) { sem_wait (&amp;s1); sem_wait (&amp;s3); putchar ('C'); sem_wait (&amp;s2); putchar ('D'); sem_post (&amp;s0); sem_wait (&amp;s1); putchar ('C'); sem_post (&amp;s3); sem_wait (&amp;s2); putchar ('D'); sem_post (&amp;s0); } return 0; } int main () { pthread_t a, b; sem_init (&amp;s0, 0, 1); sem_init (&amp;s1, 0, 0); sem_init (&amp;s2, 0, 0); sem_init (&amp;s3, 0, 0); pthread_create (&amp;a, 0, process_A, 0); pthread_create (&amp;b, 0, process_B, 0); pthread_join (a, 0); pthread_join (b, 0); putchar ('\n'); return 0; } </code></pre> <p>I will leave you to implement b) by yourself :)</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload