测试unix/linux系统PV操作的性能示例 之二【多个进程竞争PV操作】

 创建信号灯程序:

 

#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; }

创建成功之后,启动多个进程去竞争。

代码:

#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>

#define	key_t	double

union semun{
	int	val;
	struct	semid_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)
{
	int	semid,i,ret;
	char	path[256]="";
	key_t	keyvalue;
	int looptime = 10000000;
	strcpy(path,"/tmp");
	struct  tms	tmsstart,tmsend;
	clock_t	start,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)
{
	int	rtn,errno;
	struct sembuf	p_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;
	}

	return	0;
}

int SemV(int id, int off)
{
	int	rtn,errno;
	struct sembuf	p_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;
	}

	return	0;
}

static void pr_times(clock_t real,struct tms *tmsstart,struct tms *tmsend)
{
	static	long	clktck = 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);
}


本次测试的目的是为了验证,在父进程fork多个子进程后,多个子进程之间的pv竞争会不会导致系统额外的开销。

(因为子进程会共享父进程的进程空间、环境变量等,验证每个子进程执行的时候会不会重新load自己进程上下文从而导致系统损耗)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值