系统调用的三种方法(以gitpid为例子)

Linux 下常见的3种系统调用方法包括有:
(1)通过glibc提供的库函数
(2)使用syscall函数直接调用相应的系统调用
(3)通过int 80指令(32位系统)或者syscall指令(64位系统)的内联汇编调用

经过调研发现,gettimeofday和clock_gettime两种函数中clock_gettime更适合测量系统调用的时间开销,因为clock_gettime函数可以精准到纳秒级别,而gettimeofday只能达到微秒级别。
通过glibc库原生提供的getpid()函数完成调用,代码如下:

1.	#include<stdio.h>  
2.	#include<sys/stat.h>  
3.	#include<unistd.h>  
4.	#include<time.h>  
5.	int main(){  
6.	    struct timespec t1 = {0, 0};   
7.	    struct timespec t2 = {0, 0};   
8.	  
9.	    pid_t pid;  
10.	  
11.	    clock_gettime(CLOCK_REALTIME, &t1);  
12.	      
13.	    pid = getpid();  
14.	  
15.	    clock_gettime(CLOCK_REALTIME, &t2);  
16.	    double duration=(t2.tv_sec - t1.tv_sec)*1000 + (t2.tv_nsec - t1.tv_nsec);  
17.	    printf("time = %.4lf ns\n",duration);  
18.	      
19.	    printf("current process's pid(getpid):%d %d\n",pid,getpid());  
20.	    return 0;  
21.	}  

通过syscall函数获取进程id代码如下:

1.	#include<stdio.h>  
2.	#include<sys/stat.h>  
3.	#include <sys/syscall.h>  
4.	#include <sys/types.h>  
5.	#include<unistd.h>  
6.	#include<time.h>  
7.	int main(){  
8.	    struct timespec t1 = {0, 0};   
9.	    struct timespec t2 = {0, 0};   
10.	    clock_gettime(CLOCK_REALTIME, &t1);  
11.	    pid_t pid;  
12.	    pid=syscall(SYS_gettid);  
13.	    clock_gettime(CLOCK_REALTIME, &t2);  
14.	      
15.	    double duration=(t2.tv_sec - t1.tv_sec)*1000 + (t2.tv_nsec - t1.tv_nsec);  
16.	    printf("time = %.4lf ns\n",duration);   
17.	  
18.	    printf("current process's pid(SYS_gettid):%d %d\n",pid,getpid());  
19.	    return 0;  
20.	}  

通过汇编方式获得进程ID方式如下:
64位内联汇编

1.	#include<stdio.h>  
2.	#include<sys/stat.h>  
3.	#include<unistd.h>  
4.	#include<time.h>  
5.	int main(){  
6.	    struct timespec t1 = {0, 0};   
7.	    struct timespec t2 = {0, 0};   
8.	    clock_gettime(CLOCK_REALTIME, &t1);  
9.	    pid_t pid;  
10.	    asm volatile(  
11.	        "mov $39, %%eax\n\t"  
12.	        "syscall\n\t"    
13.	        :"=a"(pid)  
14.	                  /*第一个冒号后的限定字符串用于描述指令中的“输出”操作数。 
15.	                    刮号中的pid将操作数与C语言的变量联系起来。 
16.	                    "a":寄存器EAX。  
17.	                    "b":寄存器EBX。  
18.	                    "c":寄存器ECX。  
19.	                    "d":寄存器EDX。 
20.	                  */  
21.	    );  
22.	  
23.	    clock_gettime(CLOCK_REALTIME, &t2);  
24.	    double duration=(t2.tv_sec - t1.tv_sec)*1000 + (t2.tv_nsec - t1.tv_nsec);  
25.	    printf("time = %.4lf ns\n",duration);  
26.	      
27.	    printf("current process's pid(ASM):%d %d\n",pid,getpid());  
28.	    return 0;  
29.	} 

32位内联汇编

1.	#include<stdio.h>  
2.	#include<sys/stat.h>  
3.	#include<unistd.h>  
4.	#include<time.h>  
5.	int main(){  
6.	    struct timespec t1 = {0, 0};   
7.	    struct timespec t2 = {0, 0};   
8.	    clock_gettime(CLOCK_REALTIME, &t1);  
9.	    pid_t pid;  
10.	    asm volatile(  
11.	        "mov $20, %%eax\n\t"  
12.	        "int $0x80\n\t"  
13.	        :"=a"(pid)  
14.	    );  
15.	  
16.	    clock_gettime(CLOCK_REALTIME, &t2);  
17.	    double duration=(t2.tv_sec - t1.tv_sec)*1000 + (t2.tv_nsec - t1.tv_nsec);  
18.	    printf("time = %.4lf ns\n",duration);  
19.	      
20.	    printf("current process's pid(ASM):%d %d\n",pid,getpid());  
21.	    return 0;  
22.	}  

32位汇编调用码
64位汇编调用码

你可能感兴趣的:(c++,c语言,开发语言)