上药三品,神与气精

曾因酒醉鞭名马 生怕情多累美人


  • 首页

  • 关于

  • 分类

  • 标签

  • 归档

  • 搜索

linux-optimize002

发表于 2018-11-29 | 分类于 linux | 阅读次数:
字数统计: 1.1k | 阅读时长 ≈ 3

cpu 上下文切换

设置好 cpu寄存器和程序计数器

依赖环境 因此叫做上下文

进程上下文切换 线程上下文切换 中断上下文切换

进程上下文切换

linux 按照特权等级 将进程的运行空间分为内核空间和用户空间

  • 内核空间ring 0 具有最高权限 可以直接访问所有资源
  • 用户空间 ring 3 只能访问受限资源 不能直接访问内存等硬件设备 必须通过系统调用陷入到内核中 才能访问这些特权资源

进程既可以在用户空间运行 也可以在内核空间中运行

  • 用户态
  • 内核态

从用户态到内核态的转变 需要通过系统调用来完成。

比如查看文件内容的时候,需要多次系统调用来完成,首先open()打开文件 然后read 读取文件内容 write 将内容写到标准输出 最后再close关闭文件

系统调用的过程中 有cpu上下文的切换

cpu寄存器里原来用户态的指令位置 需要先保存起来 接着为了执行内核态代码 cpu寄存器需要更新为内核态的新位置 最后才是跳到内核态运行内核任务

系统调用恢复之后cpu寄存器需要恢复 需要再切换一次

一次系统调用 发生了两次上下文切换

系统调用 被称为特权模式切换 而不是上下文切换

进程的切换只能发生在内核态 因此进程的上下文不仅包括了虚拟内存、栈、全局变量等用户空间的资源,还包括了内核堆栈、寄存器等内核空间的状态

进程的上下文切换 比系统调用多了一步

在保存当前进程的内核状态和cpu寄存器之前 需要先把该进程的虚拟内存、栈等保存起来 而加载下一进程的内核态之后 还需要刷新进程的虚拟内存和用户栈

进程一和进程二之间 包含进程1上下文保存和加载进程2上下文

每次上下文的切换 都需要几十纳秒到数微秒的cpu时间 这个时间还是相当可观的

线程和进程的最大区别在于 线程是调度的基本单位 而进程则是资源拥有的基本单位

进程只是給线程提供了虚拟内存、全局变量等资源

当进程只有一个线程时 可以认为进程就等于线程

线程会共享相同的虚拟内存和全局变量等资源 这些资源在上下文切换的时候 是不需要修改的

线程也有自己的私有数据 比如栈和寄存器

线程的切换

  • 不属于同一进程的时候 因为资源不共享 所以切换和进程时一样的
  • 属于同一进程 因为虚拟内存是共享的 只需要切换线程的私有数据结构 栈 寄存器这些不共享的数据

同进程内的线程切换 要比对进程之间的切换消耗更少的资源 这也是多线程代替多进程的一个优势

中断上下文切换

为了快速响应硬件的事件 中断处理会打断进程的正常调度和执行 转而调用中断处理程序 响应设备事件

中断上下文切换不涉及到进程的用户态

对同一个cpu来说 中断处理比进程拥有更高的优先级

cpu上下文切换 是保证linux系统正常工作的核心功能之一
过多的上下文切换 会把cpu时间消耗在寄存器 内核栈 虚拟内存等数据结构的保存和恢复上

1
vmstat 5
  • context switch
  • interrupt
  • r(running or runnable)
  • b blocked 则是处于不可中断睡眠状态的进程数
1
pidstat -w 5
1
apt install sysbench
1
sysbench --threads=10 --max-time=300 threads run
  • 自愿上下文切换变多 说明进程都在等待资源 有可能发生了io等其他问题
  • 非自愿上下文切换变多 说明进程都在被强制调度 都在争取cpu
  • 中断次数变多说明cpu被中断处理程序占用 还需要通过查看 /proc/interrupts 具体问题具体分析

linux-optimize001

发表于 2018-11-29 | 分类于 linux | 阅读次数:
字数统计: 576 | 阅读时长 ≈ 2

什么是平均负载?

如何彻底理解现象背后的本质原理,用起来更加灵活,也更有底气。

uptime 命令 每一列的输出含义

当前时间 系统运行时间 正在登录的用户数

依次是过去一分钟 五分钟 15分钟的平均负载

平均负载是其实简单理解 就是平均活跃进程数

平均负载为2 时 代表什么?

  • 在2核的cpu的系统上 代表所有的cpu都刚好被完全占用
  • 在4核的cpu的系统上 代表有50%的空闲
  • 在1核的cpu的系统上 意味着有一半的进程竞争不到cpu

那么

平均负载为多少时合理?

一般而言 最理想的情况是等于cpu的个数 首先得知道系统有几个cpu

1
grep 'model name' /proc/cpuinfo | wc -l

有了cpu的个数 可以判断出平均负载比cpu的个数还大的时候,系统已经出现了过载。

一半当平均负载高于cpu数量70%的时候,就应该分析排查负载高的问题了

平均负载是单位时间内,处于可运行状态和不可中断状态的进程数,因此不止包括了正在使用cpu的进程,还包括等待cpu和等待io的进程

cpu使用率 是单位时间内cpu繁忙情况的统计 跟平均负载并不一定完全对应

  • cpu密集型时 两者一致
  • io密集时 等待io也会导致平均负载很高 但是cpu使用率不一定很高
  • 大量等待cpu的进程调度也会导致平均负载升高,此时的cpu使用率也会比较高

善于使用工具

使用 iostat mpstat pidstat 等工具 找到平均负载升高的根源在哪里

1
apt install stress sysstat -y

压力测试工具

异常进程模拟平均负载升高的场景

1
stress --cpu 1 --timeout 600
1
watch -d uptime
1
mpstat -P ALL 5
1
pidstat -u 5 1
1
stress -i 1 --timeout 600

模拟大量进程

1
stress -c 8 --timeout 600

iowait 无法升高的原因 是因为使用的是sync()系统调用 作用是刷新缓冲内存到磁盘中 可以使用下一代 stress-ng

htop atop 命令 也可以使用

leetcode-212

发表于 2018-11-27 | 阅读次数:
字数统计: 182 | 阅读时长 ≈ 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
from collections import defaultdict


dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]

END_OF_WORD = "#"


class Solution(object):
def findWords(self, board, words):
if not board or not board[0]:
return []
if not words:
return []

self.result = set()

root = defaultdict()

for word in words:
node = root
for char in word:
node = node.setdefault(char, defaultdict())
node[END_OF_WORD] = END_OF_WORD

self.m, self.n = len(board), len(board[0])

for i in xrange(self.m):
for j in xrange(self.n):
if board[i][j] in root:
self._dfs(board, i, j, "", root)

return list(self.result)


def _dfs(self, board, i, j, cur_word, cur_dict):
cur_word += board[i][j]
cur_dict = cur_dict[board[i][j]]

if END_OF_WORD in cur_dict:
self.result.add(cur_word)

tmp, board[i][j] = board[i][j], "@"
for k in xrange(4):
x, y = i + dx[k], j + dy[k]
if 0 <= x < self.m and 0 <= y < self.n \
and board[x][y] != "@" and board[x][y] in cur_dict:
self._dfs(board, x, y, cur_word, cur_dict)
board[i][j] = tmp

oracle-django-研发记录

发表于 2018-11-14 | 阅读次数:
字数统计: 55 | 阅读时长 ≈ 1
1
2
3
oracle-instantclient12.1-basic-12.1.0.2.0-1.x86_64.rpm
oracle-instantclient12.1-devel-12.1.0.2.0-1.x86_64.rpm
oracle-instantclient12.1-sqlplus-12.1.0.2.0-1.x86_64.rpm

三个客户文件是否都需要安装 每个到底做了什么

架构设计的学习

发表于 2018-10-16 | 分类于 architecture | 阅读次数:
字数统计: 0 | 阅读时长 ≈ 1
1…686970…109
John Cheung

John Cheung

improve your python skills

543 日志
33 分类
45 标签
RSS
GitHub Email
© 2020 John Cheung
本站访客数:
|
主题 — NexT.Pisces v5.1.4
博客全站共226.3k字