Open arthur-zhang opened 3 years ago
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void *fun_test(void *args) {
while(1){
pthread_mutex_lock(&mutex);
usleep(3);
pthread_mutex_unlock(&mutex);
int a = 0;
for(a = 0; a < 10000 ; a = a + 1 ){
printf("hello world\n");
}
}
}
int main() {
int num = 100;
pthread_t threads[num];
int i;
for (i = 0; i < num; ++i) {
pthread_create(&threads[i], NULL, fun_test, NULL);
}
for (i = 0; i < num; ++i) {
pthread_join(threads[i], NULL);
}
return 0;
}
从上面代码中我们可以分析到,从mian函数中我们创建了100个线程去执行fun_test 方法
1. fun_test中会调用所有的线程都回去竞争全局锁 mutex 拿到的线程再去执行 usleep 3微妙,
2. 拿到锁的线程然后打印1000次的hello world
在上述的两个过程中是存在会出现off-cpu的地方
1. 一个发生在因为usleep 导致竞争锁的时候
2. 一个发生在打印的时候,打印的时候会进行sys_write系统调用后,sys_write中有一个tty_write的n_tty_write等待一个mutex的代码上面。
sudo ./sample-bt-off-cpu -p 'pidof a.out' -t 2 -u > tmp.bt
./stackcollapse-stap.pl tmp.bt > flame.cbt
./flamegraph.pl flame.cbt > flame.svg
可以看到sample-bt-off-cpu 是监听了获取到CPU和失去CPU的两个事件,通过这两个事件之前的时间差值计算出,堆栈在0ff-cpu上的时间,然后通过时间计算出堆栈在off-cpu的比例,与获取on-cpu不同的是,on-cpu是根据定时器很高频率的对还在运行中的堆栈做计数计算的,但是off-cpu是监听的在cpu获取和失去的时间差值统计的。
计算机系统的各种硬件资源是有限的,在现代多任务操作系统上同时运行的多个进程都需要访问这些资源,为了更好的管理这些资源进程是不允许直接操作的,所有对这些资源的访问都必须有操作系统控制。也就是说操作系统是使用这些资源的唯一入口,而这个入口就是操作系统提供的系统调用(System Call),系统调用和普通库函数调用非常相似,只是系统调用由操作系统核心提供,运行于内核态,而普通的函数调用由函数库或用户自己提供,运行于用户态。
在linux中系统调用是用户空间访问内核的唯一手段,除异常和陷入外,他们是内核唯一的合法入口。操作系统一般是通过中断从用户态切换到内核态。中断就是一个硬件或软件请求,要求CPU暂停当前的工作,去处理更重要的事情。
系统调用在用户空间进程和硬件设备之间添加了一个中间层。该层主要作用有三个:
strace 在linux系统中某个程序执行时进行的系统调用可以通过strace命令来查看,多线程的线程必须加上 -f 参数
作业: 生成一个 off cpu 火焰图