Thread Synchronization


Introduction

This article shows a basic example of how two threads may synchronize on a binary semaphore. The idea is to use a semaphore to ensure that one thread, t1, does not proceed in the execution before another thread, t2, has gotten to a certain point.

There are three files in the example:

Source code

//======================
/// main.cpp
//======================
 
#include<taskLib.h>
#include<semLib.h>
 
// Prototypes for thread functions
void t1(SEM_ID id);
void t2(SEM_ID id);
 
void myMain()
{
 // construct the binary semaphore (initially empty)
 SEM_ID bid = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
 
 // Spawn (= create & activate) the two tasks
 taskSpawn("Thread 1", 100, 0, 0x1000, (FUNCPTR)t1, (int)bid, 0, 0, 0, 0, 0, 0, 0, 0, 0);
 taskSpawn("Thread 2", 100, 0, 0x1000, (FUNCPTR)t2, (int)bid, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}

//==============================
// t1.cpp
// ==============================
 
#include<taskLib.h>
#include<semLib.h>
#include<iostream>
 
using namespace std;
 
 
void t1(SEM_ID id)
{
 cout << "This is t1 executing" << endl;
 cout << "t1 will now sync with t2" << endl;
 semTake(id, WAIT_FOREVER); // Sync point - wait for t2 to give the semaphore
 cout << "t1 was allowed to continue" << endl;
 taskSuspend(100);
}

//==============================
//t2.cpp
//==============================
 
#include<taskLib.h>
#include<semLib.h>
#include<iostream>
 
using namespace std;
 
void t2(SEM_ID id)
{
 // Start with a wait - let t1 execute until sync point
 taskDelay(100);
 cout << " This is t2 finally waking up" << endl;
 cout << " t2 will now sync with t1" << endl;
 semGive(id); // Sync point - allow t1 to continue
 cout << " t2 continues execution" << endl;
}

Output result

The result of executing myMain() as shown above is as follows:
-> myMain
This is t1 executing
t1 will now sync with t2
 This is t2 finally waking up
 t2 will now sync with t1
 t2 continues execution
t1 was allowed to continue
value = 0 = 0x0
->