0

I am trying to conduct strict alternation on 2 processes, but I am not sure how to declare the critical region and non-critical region. Here is the code that I have:

    #include <iostream>
#include <pthread.h>


int count;
int turn = 0;   //  Shared variable used to implement strict alternation


void* myFunction(void* arg)
{
    int actual_arg = *((int*) arg);

    for(unsigned int i = 0; i < 10; ++i) {

      while(1)
      {
          while(turn != 0)
          {
              critical_region_0();
              turn = 1;
              non_critical_region_0();
          }
      }

      //  Beginning of the critical region

      count++;
      std::cout << "Thread #" << actual_arg << " count = " << count << 
      std::endl;

      //  End of the critical region

      while(0)
      {
          while(turn != 1)
          {
              critical_region_1();
              turn = 0          
              non_critical_region_1();
          }
      }


    }

    pthread_exit(NULL);
}

int main()
{
    int rc[2];
    pthread_t ids[2];
    int args[2];

    count = 0;
    for(unsigned int i = 0; i < 2; ++i) {
        args[i] = i;
        rc[i] = pthread_create(&ids[i], NULL, myFunction, (void*) &args[i]);
    }

    for(unsigned int i = 0; i < 2; ++i) {
        pthread_join(ids[i], NULL);
    }

    std::cout << "Final count = " << count << std::endl;
    pthread_exit(NULL);
    }

I know that the critical region and non-critical regions are written as if they are a method but I am using those as placeholders. Is there a way to conduct Strict Alternation without the use of these methods?

Here is what the output should look like.

Thread #0 count = 1
Thread #1 count = 2
Thread #0 count = 3
Thread #1 count = 4
Thread #0 count = 5
Thread #1 count = 6
Thread #0 count = 7
Thread #1 count = 8
Thread #0 count = 9
Thread #1 count = 10
Thread #0 count = 11
Thread #1 count = 12
Thread #0 count = 13
Thread #1 count = 14
Thread #0 count = 15
Thread #1 count = 16
Thread #0 count = 17
Thread #1 count = 18
Thread #0 count = 19
Thread #1 count = 20
Final count = 20

The output I can only manage to get is all of thread 1 first then thread 0.

Jdmon1998
  • 31
  • 6
  • 1
    Yes , you can use std::atomic_flag::test_and_set instead, but it works for different threads on the same process. By the way, your question title reads "String" Alternation instead of strict, and you are also mixing the terminology for process and threads. They are 2 different things. – Gonen I Feb 02 '18 at 17:14
  • Looks like an XY problem, why do you need threads to work like this? – Slava Feb 02 '18 at 17:19
  • @Slava I need it to work like this so that I can learn how to implement Strict Alternation. I did not realize that my question said String Alternation, I realize that they are two different things. – Jdmon1998 Feb 02 '18 at 18:01
  • Yea but question is what you would need "Strict Alternation" for. Looks like useless paradigm to me. – Slava Feb 02 '18 at 18:13

1 Answers1

0

I think this is a classic place for signals. Each function controlling the thread looks like (thread 1 for example)

while( ... ) {
...
pthread_cond_signal(thread1_done_work);
pthread_cond_wait(thread_2_done_work);
}

where both the work variables are globals of type pthread_cond_t - I think it's more readable with two, but you don't have to use two (a mutex implementation comes to mind).

Thread 2 needs a wait condition as soon as it starts. Here are some details:

https://linux.die.net/man/3/pthread_cond_wait

https://linux.die.net/man/3/pthread_cond_signal

Basically each thread signals it's done (this blocks until the other thread is ready to catch this), then waits for the other thread. So they're "talking" my turn, your turn, etc. If you insist on using the same function for both threads you can pace the condition variables as arguments (swapped for thread 2 relative to 1).

One final small note - this somewhat contradicts the whole purpose of threading.

kabanus
  • 24,623
  • 6
  • 41
  • 74