Multi-Process Synchronization in Linux: For multi-process synchronization in Linux, the operation of a single semaphore is no longer possible. For multi-process communication, the signal set method can be used, A signal set contains multiple semaphores.
First, create a semaphore through semget. Example: Semid = semget (semkey, 2,0600 | iflags;
Then, assign the initial values to each semaphore in the signal set:
Semctl (Semid, 0, setval, 0 );
Semctl (Semid, 1, setval, 1 );
You can also use set_sem_value (Semid,) to assign an initial value of 1 to the first semaphore whose signal set is Semid.
Void set_sem_value (INT Semid, int num, int Val)
{
Union semun semun_info;
Semun_info.val = val;
Semctl (Semid, 0, setval, semun_info );
}
Then there is an operation similar to the PV primitive.
Note:
Struct sembuf p1 = {0,-1, 0}, P2 = {1,-1, 0 },
V1 = {0, 1}, V2 = {1, 1, 0 };
Then, use int semop (INT Semid, struct sembuf * SOPs, unsigned nsops); To perform PV operations !. The specific code is as follows:
/************************************ Produce. c *******************************/
# Include <stdio. h>
# Include <stdlib. h>
# Include <unistd. h>
# Include <string. h>
# Include <fcntl. h>
# Include <sys/time. h>
# Include <sys/Mman. h>
# Include <sys/IOCTL. h>
# Include <sys/types. h>
# Include <sys/IPC. h>
# Include <sys/SHM. h>
# Include <sys/SEM. h>
# Include <errno. h>
# Define shmkey (key_t) 0x100
# Define semkey (key_t) 0x200
# Define iflags (ipc_creat | ipc_excl)
# Define err (struct databuf *)-1)
Struct databuf {
Int d_buf [10];
};
Static int shmid, Semid;
Pr_error (char * mess)
{
Perror (MESS );
Exit (1 );
}
Getseg (struct databuf ** pdata)
{
/* Obtain the key of the shared memory. If no key is set up, set it to ipc_creat )*/
If (shmid = shmget (shmkey, sizeof (struct databuf), 0600 | iflags) <0)
{
If (errno = eexist)
{
Shmid = shmget (shmkey, sizeof (struct databuf), 0600 | ipc_creat );
If (shmid <0)
Pr_error ("shmget ");
}
Else
Pr_error ("shmget ");
}
/* Get the shared memory pointer. When using the shared memory, it can be the same as the memory allocated by malloc */
If (* pdata = (struct databuf *) (shmat (shmid, 0, 0) = ERR)
Pr_error ("shmat ");
}
Int getsem ()
{/* Create a semaphore (also called a and B )*/
If (Semid = semget (semkey, 2,0600 | iflags) <0)
{
If (errno = eexist)
{
Semid = semget (semkey, 2,0600 | ipc_creat );
If (Semid <0)
Pr_error ("semget ");
Else
/* Add this sentence. if it already exists, no semaphores will be initialized */
Return Semid;
}
Else
Pr_error ("semget ");
}
/* Set the initial value of semaphore A to 0 */
If (semctl (Semid, 0, setval, 0) <0)
Pr_error ("semctl ");
/* Set the initial value of semaphore B to 1 */
If (semctl (Semid, 1, setval, 1) <0)
Pr_error ("semctl ");
Return (Semid );
}
Void remove_s ()
{
/* Delete shared memory */
If (shmctl (shmid, ipc_rmid, null) <0)
Pr_error ("shmctl ");
/* Delete semaphores */
If (semctl (Semid, ipc_rmid, null) <0)
Pr_error ("semctl ");
}
Main ()
{
Int Semid;
Struct databuf * Buf;
Semid = getsem ();
Getseg (& BUF );
Writer (Semid, Buf );
Remove_s ();
Exit (0 );
}
Struct sembuf p1 = {0,-1, 0}, P2 = {1,-1, 0 },
V1 = {0, 1}, V2 = {1, 1, 0 };
Writer (INT Semid, struct databuf * BUF)
{
Int I, J;
For (I = 0; I <10; I ++ ){
/* P (B) B = 0; Prepare the write buffer */
Printf ("next loop \ n ");
Semop (Semid, & p2, 1 );
/* Write shared memory */
For (j = 0; j <10; j ++ ){
Buf-> d_buf [J] = 10 * I + J;
Printf ("Buf-> d_buf [% d] = % d \ n", J, Buf-> d_buf [J]);
}
Sleep (5 );
/* V (a) A = 1, wake up the consumer process, read the buffer */
Semop (Semid, & V1, 1 );
}
Return;
}
/**************************** Consumer. c ***************************/
# Include <stdio. h>
# Include <stdlib. h>
# Include <unistd. h>
# Include <string. h>
# Include <fcntl. h>
# Include <sys/time. h>
# Include <sys/Mman. h>
# Include <sys/IOCTL. h>
# Include <sys/types. h>
# Include <sys/IPC. h>
# Include <sys/SHM. h>
# Include <sys/SEM. h>
# Include <errno. h>
# Define shmkey (key_t) 0x100
# Define semkey (key_t) 0x200
# Define iflags (ipc_creat | ipc_excl)
# Define err (struct databuf *)-1)
Struct databuf {
Int d_buf [10];
};
Static int shmid, Semid;
Pr_error (char * mess)
{
Perror (MESS );
Exit (1 );
}
Getseg (struct databuf ** pdata)
{
/* Obtain the key of the shared memory. If no key is set up, set it to ipc_creat )*/
If (shmid = shmget (shmkey, sizeof (struct databuf), 0600 | iflags) <0)
{
If (errno = eexist)
{
Shmid = shmget (shmkey, sizeof (struct databuf), 0600 | ipc_creat );
If (shmid <0)
Pr_error ("shmget ");
}
Else
Pr_error ("shmget ");
}
/* Get the shared memory pointer. When using the shared memory, it can be the same as the memory allocated by malloc */
If (* pdata = (struct databuf *) (shmat (shmid, 0, 0) = ERR)
Pr_error ("shmat ");
}
Int getsem ()
{/* Create a semaphore (also called a and B )*/
If (Semid = semget (semkey, 2,0600 | iflags) <0)
{
If (errno = eexist)
{
Semid = semget (semkey, 2,0600 | ipc_creat );
If (Semid <0)
Pr_error ("semget ");
Else
/* Add this sentence. if it already exists, no semaphores will be initialized */
Return Semid;
}
Else
Pr_error ("semget ");
}
/* Set the initial value of semaphore A to 0 */
If (semctl (Semid, 0, setval, 0) <0)
Pr_error ("semctl ");
/* Set the initial value of semaphore B to 1 */
If (semctl (Semid, 1, setval, 1) <0)
Pr_error ("semctl ");
Return (Semid );
}
Main ()
{
Int Semid;
Struct databuf * Buf;
Semid = getsem ();
Getseg (& BUF );
Reader (Semid, Buf );
Exit (0 );
}
Struct sembuf p1 = {0,-1, 0}, P2 = {1,-1, 0 },
V1 = {0, 1}, V2 = {1, 1, 0 };
Reader (INT Semid, struct databuf * BUF)
{
Int I, J;
For (I = 0; I <10; I ++ ){
/* P (A) A =-1. If there is no data, blocking, and yes, read */
Printf ("next loop \ n ");
Semop (Semid, & P1, 1 );
For (j = 0; j <10; j ++ ){
Printf ("% d", Buf-> d_buf [J]);
}
Printf ("\ n ");
Semop (Semid, & V2, 1 );
/* V (B) B ++, wake up the write process */
}
Return;
}