# Include <sys/types. h>
# Include <sys/IPC. h>
# Include <sys/SEM. h>
# Include <pthread. h>
# Include <errno. h>
# Include <vector>
# Include <iostream>
Using namespace STD;
Union semun {
Int val;/* value for setval */
Struct semid_ds * Buf;/* buffer for ipc_stat, ipc_set */
Unsigned short * array;/* array for getall, setall */
Struct seminfo * _ Buf;/* buffer for ipc_info
(Linux specific )*/
};
// Working thread function
Void * workproc (void * PARAM)
{
Int SID = * (int *) Param; // semaphore ID
Pthread_t tid = pthread_self (); // thread ID
Cout <"Thread" <TID <"/t opt 1 is OK! "<Endl; // The first step is completed.
// Semaphores minus 1
Sembuf B;
B. sem_num = 0;
B. sem_op =-1;
B. sem_flg = 0;
Int ret = semop (SID, & B, 1 );
If (Ret! = 0)
Return (void *)-1;
// Wait until the semaphore is 0
Cout <"Thread" <TID <"/t begin wait for all thread OK! "<Endl;
B. sem_op = 0;
Ret = semop (SID, & B, 1 );
If (Ret! = 0)
Return (void *)-1;
Cout <"Thread" <TID <"/t end wait for all thread OK! "<Endl;
// Perform Step 2
Cout <"Thread" <TID <"/T opt 2 is OK! "<Endl;
Return 0;
}
Int main ()
{
// Create a semaphore
Int SID = semget (ipc_private, 1, ipc_creat | 0660 );
If (SID =-1)
{
Cout <"create SEM error! "<Endl;
Return-1;
}
// Set the initial semaphore value to 5.
Semun UN;
Un. Val = 5;
Int ret = semctl (SID, 0, setval, UN );
If (ret =-1)
Return-1;
// Start a group of working threads
Vector <pthread_t> IDs; // stores the startup thread ID array.
Pthread_t ID;
For (INT I = 0; I <5; ++ I)
{
Pthread_create (& ID, null, workproc, & SID );
IDs. push_back (ID );
}
// Wait until all worker threads end
Int num = IDs. Size ();
For (INT I = 0; I <num; ++ I)
{
Pthread_join (IDs [I], null );
}
// Delete semaphores
Semctl (SID, 1, ipc_rmid );
Return 1;
}