Create a traffic signal program:
# Include <stdio. h> # include <stdlib. h> # include <unistd. h> # include <sys/types. h> # include <sys/STAT. h> # include <fcntl. h> # include <sys/IPC. h> # include <sys/SEM. h> # include <ASM/errno. h> # include <errno. h>
# Define key_t double
Union semun {int val; struct semid_ds * Buf; ushort * array;} para;
Pid_t start_process (char * prgname );
Int main (INT argc, char ** argv) {int Semid, oflags, nsems; int op_flag, ID; char path [256] = ""; char prgname [256]; key_t keyValue; int I, RET; int semsem, looptime;
If (argc! = 4) {printf ("useage:./semop path nsems op_flag \ n"); exit (0 );}
Strcpy (path, argv [1]); nsems = atoi (argv [2]); op_flag = atoi (argv [3]);
Printf ("You input ARGs is: \ n"); printf ("Path: % s \ t nsems: % d \ t op_flag: % d \ t \ n", path, nsems, op_flag );
Oflags = 0666 | ipc_creat | ipc_excl; keyValue = ftok (path,'s ');
If (op_flag = 0) {/* Create SEM */If (Semid = semget (keyValue, nsems, oflags) <0) {fprintf (stderr, "semget create failed! Errno is % d \ n ", errno); exit (0 );}
/* Init SEM values */for (I = 0; I <nsems; I ++) {para. val = 1; if (ret = semctl (Semid, I, setval, para) <0) printf ("SEM % d Set Value failed! \ N ", I);} printf (" semop create OK! \ Nsemid is % d \ n ", Semid );}
If (op_flag = 1) {If (Semid = semget (keyValue, 0,0666) <0) {printf ("semget read failed! Errno is % d \ n ", errno); exit (-1 );}
/* Fork process and exec PV */for (I = 0; I <nsems; I ++) {sprintf (prgname, "/home/Tong/yaodl/sempv % d", I); If (ret = start_process (prgname) <0) {printf ("create process failed! \ N "); exit (-1 );}}}
/* Del SEM */If (op_flag = 2) {If (Semid = semget (keyValue, 0,0666) <0) {printf ("semget read failed! Errno is % d \ n ", errno); exit (-1);} If (semctl (Semid, 0, ipc_rmid, 0) <0) {printf ("semop Delete failed! Semid is % d \ n ", Semid);} else printf (" semop Delete OK! \ Nsemid is % d \ n ", Semid );}
Return 0 ;}
Pid_t start_process (char * prgname) {pid_t PID;
Switch (pid = fork () {Case 0: If (execvp (prgname, null) <0) {fprintf (stderr, "start_process execvp error, [% s]", prgname );}
Exit (0); Case-1: fprintf (stderr, "start_process fork error, [% s]", prgname); pid = 0; break ;}
Return PID ;}
After the creation is successful, start multiple processes to compete.
Code:
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <time.h>#include <sys/timeb.h>#include <sys/times.h>#include <fcntl.h>#include <sys/ipc.h>#include <sys/sem.h>#include <asm/errno.h>#include <errno.h>#definekey_tdoubleunion semun{intval;structsemid_ds *buf;ushort*array;}para;int SemP(int id, int off,int flag);int SemV(int id, int off);static void pr_times(clock_t real,struct tms *tmsstart,struct tms *tmsend);int main(int argc,char **argv){intsemid,i,ret;charpath[256]="";key_tkeyvalue;int looptime = 10000000;strcpy(path,"/tmp");struct tmstmsstart,tmsend;clock_tstart,end;keyvalue = ftok(path, 'S');/* PV opration */if((semid = semget(keyvalue,0,0666)) < 0){printf("semget read failed!errno is %d\n",errno);exit(-1);}if((start = times(&tmsstart)) == -1){printf("starting time failed!\n");exit(-1);}for(i=0;i<looptime;i++){if(SemP(semid,0,1) < 0){printf("SemP failed!i=%d\n",i);exit(-1);}if(SemV(semid,0) < 0){printf("SemV failed!i=%d\n",i);exit(-1);}}if((end = times(&tmsend)) == -1){printf("ending time failed!\n");exit(-1);}pr_times(end-start,&tmsstart,&tmsend);return 0;}int SemP(int id, int off, int flag){intrtn,errno;struct sembufp_buf;p_buf.sem_num = off;p_buf.sem_op = -1;if (flag)p_buf.sem_flg = SEM_UNDO;while(1){rtn=semop(id, &p_buf, 1);if( rtn < 0 ){if( errno == EINTR ) continue;else return -1;}break;}return0;}int SemV(int id, int off){intrtn,errno;struct sembufp_buf;p_buf.sem_num = off;p_buf.sem_op = 1;p_buf.sem_flg = SEM_UNDO;while(1){rtn=semop(id, &p_buf, 1);if( rtn < 0 ){if( errno == EINTR ) continue;else return -1;}break;}return0;}static void pr_times(clock_t real,struct tms *tmsstart,struct tms *tmsend){staticlongclktck = 0;if(clktck == 0){if((clktck = sysconf(_SC_CLK_TCK)) < 0){printf("sysconf error!\n");exit(-1);}}fprintf(stderr,"sempv0");fprintf(stderr,"real:%7.2f\n",real/(double)clktck);fprintf(stderr,"user:%7.2f\n",(tmsend->tms_utime - tmsstart->tms_utime)/(double)clktck);fprintf(stderr,"sys:%7.2f\n",(tmsend->tms_stime - tmsstart->tms_stime)/(double)clktck);}
The purpose of this test is to verify whether PV competition between multiple child processes after the parent process fork leads to additional system overhead.
(Because the sub-process will share the process space and environment variables of the parent process, and verify whether each sub-process will re-load its own process context during execution, resulting in system loss ).