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. }