IPC. h
# Pragma once # ifndef _ ipc_h # DEFINE _ ipc_h # include <stdio. h> # include <stdlib. h> # include <sys/types. h> # include <sys/IPC. h> # include <sys/SHM. h> # include <sys/SEM. h> # include <unistd. h> # define bufsz 256 // describe the prototype of a set of functions created or obtained by IPC. Int p_operation (INT sem_id); int v_operation (INT sem_id); int get_ipc_id (char * proc_file, key_t key); char * set_shm (key_t shm_key, int shm_num, int shm_flag); int set_sem (key_t sem_key, int sem_val, int sem_flag ); /* community for traffic signal control */typedef Union semuns {int val;} sem_uns; // producer consumer shared buffer, that is, the related variable key_t buff_key; int buff_num; char * buff_ptr; // The sharing pointer key_t pput_key; int pput_num; int * pput_ptr; // The consumer obtains the sharing pointer key_t cget_key; int cget_num; int * cget_ptr; // producer-related semaphores key_t prod_key; // IPC Key Identifier int prod_sem; // producer-synchronized semaphores // consumer-related semaphores key_t cons_key; // IPC Key Identifier int cons_sem; // consumer synchronization semaphores int sem_val; int sem_flg; int shm_flg;/* mutex semaphores */key_t mtx_key; // IPC key identification int mtx_sem; // mutex semaphores # endif
IPC. c
# Include "IPC. H "/** get_ipc_id () obtain the ID of IPC from/proc/sysvipc/File System * pfile: the IPC files in the/proc/sysvipc/directory are * MSG-message queue, SEM-semaphore, and SHM-shared memory * key: key value corresponding to the ID of the IPC to be obtained */INT get_ipc_id (char * proc_file, key_t key) {file * PF; int I, j; char line [bufsz], colum [bufsz]; If (pF = fopen (proc_file, "R") = NULL) {perror ("proc file not open"); exit (exit_failure );} fgets (line, bufsz, Pf); While (! Feof (PF) {I = J = 0; fgets (line, bufsz, Pf); While (line [I] = '') I ++; while (line [I]! = '') Colum [J ++] = line [I ++]; Colum [J] = '/0'; If (atoi (colum )! = Key) continue; j = 0; while (line [I] = '') I ++; while (line [I]! = '') Colum [J ++] = line [I ++]; Colum [J] = '/0'; I = atoi (colum); fclose (PF ); return I;} fclose (PF); Return-1 ;}{// create a shared memory with a length of shm_num bytes, the label is returned to shm_id if (shm_id = shmget (shm_key, shm_num, shm_flg) <0) {perror ("sharememory set error"); exit (exit_failure );} // shmat attaches the shared memory identified by shm_id to the pointer shm_buf if (shm_buf = (char *) shmat (shm_id,) <(char *) 0) {perror ("Get sharememory error"); exit (exit_failure);}/* shared memory zone initialization */for (I = 0; I <shm_num; I ++) shm_buf [I] = 0; // The initial value is 0} // the shared memory area marked by the shm_key has been created, attach the shared memory identified by shm_id to the pointer shm_buf if (shm_buf = (char *) shmat (shm_id,) <(char *) 0) {perror ("Get sharememory error"); exit (exit_failure);} return shm_buf ;}
Producer. c
# Include "IPC. H "int main (INT argc, char * argv []) {int rate; // you can specify the number of seconds for a process to sleep in the first parameter of the command line, to mediate the process execution speed if (argv [1]! = NULL) rate = atoi (argv [1]); else rate = 3; // The variable used for shared memory is not specified as 3 seconds. The key value is assigned, however, pay attention to the // uniqueness of the key value. To use the same shared memory in another file, use the unified key value buff_key = 101; // the key value buff_num = 8 given by any buffer zone; // The length of the buffer zone is pput_key = 102; // The producer puts the product pointer's key value pput_num = 1; // The number of pointers shm_flg = ipc_creat | 0644; // shared memory read/write permission // obtain the shared memory used by the buffer. buff_ptr points to the first address of the buffer buff_ptr = (char *) set_shm (buff_key, buff_num, shm_flg ); // obtain the producer's position pointer pput_ptr = (int *) set_shm (pput_key, pput_num, shm_flg); // The variable used by the semaphore prod_key = 201; // producer synchronization traffic signal key value mtx_key = 202; // mutex traffic signal key value cons_key = 301; // consumer synchronization traffic signal key value sem_flg = ipc_creat | 0644; // The initial value of the producer synchronization signal light is set to the maximum available buffer sem_val = buff_num; // obtain the producer synchronization signal light and reference the identifier prod_sem = set_sem (prod_key, sem_val, sem_flg ); // The initial value of the synchronization signal lamp is set to 0 sem_val = 0; // the initial value of the synchronization signal lamp is obtained. The reference mark is saved as cons_sem = set_sem (cons_key, sem_val, sem_flg ); // The initial value of the producer mutex signal is 1 sem_val = 1; // obtain the mutex signal, and reference the identifier mtx_sem = set_sem (mtx_key, sem_val, sem_flg ); // cyclically execute the simulation producer to keep releasing the product while (1) {// If the buffer is full, the producer blocks p_operation (prod_sem); // if a process enters, this producer blocks p_operation (mtx_sem); // The producer can write a single character to simulate product placement by the producer, report the current process number and characters, and the storage location buff_ptr [* pput_ptr] = 'A' + * pput_ptr; // suspend rate second // sleep (rate ); printf ("% d producer put: % C to buffer [% d] \ n", getpid (), buff_ptr [* pput_ptr], * pput_ptr ); // The storage position is moved down cyclically * pput_ptr = (* pput_ptr + 1) % buff_num; // wake up the blocked process v_operation (mtx_sem ); // wake up the blocked consumer v_operation (cons_sem);} return exit_success ;}
Consumer
# Include "IPC. H "int main (INT argc, char * argv []) {int rate; // you can specify the number of seconds for a process to sleep in the first parameter of the command line, to mediate the process execution speed if (argv [1]! = NULL) rate = atoi (argv [1]); else rate = 3; // The variable buff_key = 101 for shared memory usage is not specified; // The key value buff_num = 8 for any buffer zone; // The length cget_key = 103 for any buffer zone; // The consumer obtains the key value cget_num = 1 for the product pointer; // Number of pointers shm_flg = ipc_creat | 0644; // shared memory read/write permission // obtain the shared memory used by the buffer. buff_ptr points to the buffer's first address buff_ptr = (char *) set_shm (buff_key, buff_num, shm_flg); // obtain the consumer's product pointer. cget_ptr points to the index address cget_ptr = (int *) set_shm (cget_key, cget_num, shm_flg); mtx_key = 202; // mutex signal key value // the initial value of the producer synchronization signal is set to the maximum available buffer sem_val = buff_num; // obtain the producer synchronization signal, reference the identifier prod_sem = set_sem (prod_key, sem_val, sem_flg); // the initial value of the synchronization signal lamp is set to 0 sem_val = 0; // obtain the synchronization signal lamp of the consumer, and reference the mark to save cons_sem = set_sem (cons_key, sem_val, sem_flg); // the initial value of the consumer mutex signal is 1 sem_val = 1; // obtain the consumer synchronization signal, and reference the mark storage cons_sem = set_sem (cons_key, sem_val, sem_flg ); // The initial value of the consumer mutex signal is 1 sem_val = 1; // obtain the mutex signal, and reference the identifier mtx_sem = set_sem (mtx_key, sem_val, sem_flg ); // cyclically execute the simulation consumer to continuously fetch the product while (1) {// if no product consumer blocks p_operation (cons_sem); // if a process enters, this consumer blocks p_operation (mtx_sem); // simulates the consumer to take the product in the form of a read character, and reports the process number, the obtained characters, and the read location. // sleep (rate ); printf ("% d consumer get: % C frombuffer [% d] \ n", getpid (), buff_ptr [* cget_ptr], * cget_ptr ); // read position move down cyclically * cget_ptr = (* cget_ptr + 1) % buff_num; // wake up the blocked process v_operation (mtx_sem ); // wake up the blocked producer v_operation (prod_sem);} return exit_success ;}
Consumer of the shared memory producer