Practice 1: Signal Volume implementation process mutex
The parent-child process execution process is as follows:
Parent process |
Child process |
P |
P |
O (print) |
X (print) |
Sleep |
Sleep |
O (print) |
X (print) |
V |
V |
Sleep |
Sleep |
As can be seen, O or X is always paired, either two O, or two x;
/**p,v Primitives implement a parent-child process mutex using terminal **///program code int main (int argc,char *argv[]) {int semid = sem_create (ipc_private); Sem_setval (Semid, 1); int count = 10; pid_t pid = fork (); if (PID = =-1) err_exit ("fork Error"); else if (PID > 0)//Sub-process {Srand (getpid ()); while (count--) {sem_p (semid); Critical section begins cout << ' X '; Fflush (stdout); Be sure to add ffflush because the interrupt is the row buffer for sleep (rand ()%3); cout << ' X '; Fflush (stdout); Critical section end Sem_v (Semid); Sleep (rand ()%3); }} else/parent process {Srand (getpid ()); while (count--) {sem_p (semid); Critical section begins cout << ' O '; Fflush (stdout); Sleep (rand ()%3); cout << ' O '; Fflush (stdout); Critical section end Sem_v (Semid); Sleep (rand ()%3); } wait (NULL); Sem_dElete (Semid); } return 0;}
Practice 2: The semaphore set solves the problem of the Philosopher's meal
Suppose there are five philosophers sitting around a round table, doing one of the following two things: eating, or thinking. When they eat, they stop thinking and they stop eating when they think. There is a fork between each of the two philosophers. Since it is difficult to eat with a fork, it is assumed that philosophers must eat with two forks, and that they can only use the two forks on their right and left hand side.
/** solution adopted is: only about two knives and forks can be used, only picked up two knives and forks to achieve a deadlock and no deadlock of the two forms of wait_2fork (see below) **/int semid;//no deadlock waitvoid wait_2fork ( Unsigned short No.) {unsigned short left = no; unsigned short right = (no+1)%5; struct SEMBUF sops[2] = {{left,-1, 0}, {right,-1, 0}}; At the same time get left and right two forks if (Semop (Semid, SOPs, 2) = =-1) err_exit ("Wait_2fork error");} /*//has a deadlock waitvoid wait_2fork (unsigned short) {unsigned short left = no; unsigned short right = (no+1)%5; struct Sembuf SOPs = {left,-1, 0}; Get the left knife and fork if (Semop (Semid, &sops, 1) = =-1) err_exit ("Wait_2fork error"); Sleep (4); Sleep for a few seconds, accelerating the generation of deadlocks Sops.sem_num = right; Get the right knife and fork if (Semop (Semid, &sops, 1) = =-1) err_exit ("Wait_2fork error");} *///release two cutlery void signal_2fork (unsigned short) {unsigned short left = no; unsigned short right = (no+1)%5; struct SEMBUF sops[2] = {{left, 1, 0}, {right, 1, 0}}; if (Semop (Semid, SOPs, 2) = =-1) err_exit ("Signal_2fork error");} philosopher void philosopher (Unsigned Short No) {Srand (Time (NULL)); while (true) {cout << no << ' is thinking ' << Endl; Sleep (rand ()%5+1); cout << No << "is Hunger" << Endl; Wait_2fork (no); Get two cutlery//dining cout << "+ +" << no << "is eating" << Endl; Sleep (rand ()%5+1); Signal_2fork (no);//Release two Knives and Forks}}
int main () { //Creates a semaphore set: Contains 5 semaphores semid = Semget (ipc_private, 5, ipc_creat|0666); if (Semid = =-1) err_exit ("Semget error"); Each semaphore is set to the initial value of 1 Union Semun su; Su.val = 1; for (int i = 0; i < 5; ++i) if (Semctl (Semid, I, Setval, su) = = 1) err_exit ("Semctl setval error"); Create four sub-processes, set the number of each process to no pid_t pid; unsigned short no = 0; For (unsigned short i = 0; i < 4; ++i) { pid = fork (); if (PID = =-1) err_exit ("fork Error"); else if (PID = = 0) { no = i+1; break; } } The last five processes (4 sub-processes + 1 parent processes) will be assembled here, //each process represents a philosopher, ref. No:0~4 philosopher (no); return 0;}
Linux IPC Practice (--system v Semaphore) (2)