系统调用的三种方法(以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位汇编调用码

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值