Title: Linux Process Communication-use semaphores
I. Related Knowledge
Semaphores: an integer;
The number of resource entities that tables can be used by concurrent processes when the value is greater than or equal to 0;
Number of processes waiting for using the critical section in the age of less than 0;
The initial semaphore value used for mutex must be greater than 0;
It can only be changed through P and V primitive operations;
Semaphore element composition:
1. The value of the semaphore element;
2. process ID of the final semaphore Element
3. The number of processes with the semaphore element value + 1;
4. Number of processes whose semaphores element value is 0;
Ii. Main Functions
1.1 create semaphores
Int semget (
Key_t key, // The Key to identify the semaphore, there are three methods: 1, the use of IPC--PRIVATE for the system to produce,
// 2. Select a random number. 3. Use ftok to generate a random number from the file path.
Int nsemes, // number of elements in the semaphore set
Int flag // ipc_creat; ipc_excl is created only when the semaphore set does not exist
)
Success: return the semaphore handle.
Failed:-1 is returned.
1.2 use the ftok function to generate a keyword Based on the file path name
Key_t ftok (const char * pathname, int proj_id );
The path name must have the corresponding Permissions
1.3 control semaphores
Int semctl (
Int Semid, // semaphore set handle
Int semnum, // number of elements in the semaphore set
Int cmd, // command
/* Union senum Arg */...//
)
Success: the corresponding value is returned.
Failed:-1 is returned.
Command details:
CMD: ipc_rmid: deletes a semaphore.
Ipc_excl is created only when the semaphore set does not exist.
Ipc_set: Set the semaphore permission
Setval: set the value of the element of the specified semaphore to AGC. Val.
Getval obtains the value of a specified semaphore.
Getpid obtains the final process ID that finally controls this element.
Getncnt obtains the number of processes that wait for the element to change to 1.
Getzcnt obtains the number of processes that wait for the element to change to 0.
Union senum is defined as follows:
Union senum {
Int val;
Struct semid_ds * Buf;
Unsigned short * array;
} AGC;
Semid_ds is defined as follows:
Struct semid_ds {
Struct ipc_pem sem_pem; // operation pemission struct
Time_t sem_otime; // last semop () Time
Time_t sem_ctime; // last time changed by semctl ()
Struct SEM * sembase; // PTR to first semaphore in array
Struct sem_queue * sem_pending; // pending operations
Struct sem_queue * sem_pending_last; // last pending operations
Struct sem_undo * undo; // undo requests on this arrary
Unsigned short int sem_nsems; // Number of semaphores in Set
};
1.4 semaphore + 1 or-1 or test whether it is 0
Int semop (
Int Semid,
Struct sembuf * SOPs, // points to the element Operation Array
Unsigned short nsops // Number of element operations in the array
)
Structure sembuf Definition
Sembuf {
Short int sem_num; // semaphore number
Short int sem_op; // semaphore operaion
Short int sem_flg // operation flag
};
Iii. Example:
2.1 servers
# Include <sys/SEM. h>
# Include <sys/IPC. h>
# Derefined segsize 1024
# Define readtime 1
Union semun {
Int val;
Struct semid_ds * Buf;
Unsigned short * array;
} ARG;
// Generate a semaphore
Int sem_creat (key_t key)
{
Union semun SEM;
Int Semid;
SEM. Val = 0;
Semid = semget (Key, 1, ipc_creat | 0666 );
If (-1 = Semid ){
Printf ("create semaphore error/N ");
Exit (-1 );
}
Semctl (Semid, 0, setval, SEM );
Return Semid;
}
// Delete semaphores
Void del_sem (INT Semid)
{
Union semun SEM;
SEM. Val = 0;
Semctl (Semid, 0, ipc_rmid, SEM );
}
// P
Int P (INT Semid)
{
Struct sembuf SOPs = {0, + 1, ipc_nowait };
Return (semop (Semid, & SOPs, 1 ));
}
// V
Int V (INT Semid)
{
Struct sembuf SOPs = {0,-1, ipc_nowait };
Return (semop (Semid, & SOPs, 1 ));
}
Int main ()
{
Key_t key;
Int shmid, Semid;
Char * SHM;
Char MSG [7] = "-data -";
Char I;
Struct semid_ds Buf;
Key = ftok ("/", 0 );
Shmid = shmget (Key, segsize, ipc_creat | 0604 );
If (-1 = shmid ){
Printf ("create shared memory error/N ");
Return-1;
}
SHM = (char *) shmat (shmid, 0, 0 );
If (-1 = (INT) SHM ){
Printf ("Attach shared memory error/N ");
Return-1;
}
Semid = sem_creat (key );
For (I = 0; I <= 3; I ++ ){
Sleep (1 );
P (Semid );
Sleep (readtime );
MSG [5] = '0' + I;
Memcpy (SHM, MSG, sizeof (MSG ));
Sleep (58 );
V (Semid );
}
Shmdt (SHM );
Shmctl (shmid, ipc_rmid, & BUF );
Del_sem (Semid );
Return 0;
// Gcc-o shm. C-G
}
2.2 Client
# Include <sys/SEM. h>
# Include <time. h>
# Include <sys/IPC. h>
# Derefined segsize 1024
# Define readtime 1
Union semun {
Int val;
Struct semid_ds * Buf;
Unsigned short * array;
} ARG;
// Print the program execution time
Void out_time (void)
{
Static long start = 0;
Time_t TM;
If (0 = Start ){
TM = Time (null );
Start = (long) TM;
Printf ("now start.../N ");
}
Printf ("Second: % LD/N", (long) (Time (null)-Start );
}
// Create a semaphore
Int new_sem (key_t key)
{
Union semun SEM;
Int Semid;
SEM. Val = 0;
Semid = semget (Key, 0, 0 );
If (-1 = Semid ){
Printf ("create semaphore error/N ");
Exit (-1 );
}
Return Semid;
}
// Wait until the semaphore is 0
Void wait_v (INT Semid)
{
Struct sembuf SOPs = {0, 0 };
Semop (Semid, & SOPs, 1 );
}
Int main (void)
{
Key_t key;
Int shmid, Semid;
Char * SHM;
Char MSG [100];
Char I;
Key = ftok ("/", 0 );
Shmid = shmget (Key, segsize, 0 );
If (-1 = shmid ){
Printf ("create shared memory error/N ");
Return-1;
}
SHM = (char *) shmat (shmid, 0, 0 );
If (-1 = (INT) SHM ){
Printf ("Attach shared memory error/N ");
Return-1;
}
Semid = new_sem (key );
For (I = 0; I <3; I ++ ){
Sleep (2 );
Wait_v (Semid );
Printf ("message geted is: % s/n", SHM + 1 );
Out_time ();
}
Shmdt (SHM );
Return 0;
// Gcc-O shmc. C-G
}
Site: http://blog.csdn.net/hfzhangyun/archive/2004/08/31/90099.aspx