Linux load average的意思就是说 目前有ready的进程 但是cpu都在满,然后这个数是一分钟的平均值。公式:loadvg = tasks running + tasks waiting (for cores) + tasks blocked. 让CPU满是最简单的方式
为了更好理解load average,Tim某天在群征集一段代码使load average最高。于是乎,群友纷纷出手。
Erlang版
[~]$ cat load10
#!/usr/bin/env escript
%% -- erlang --
%%! -smp enable -sname load10
main(_) ->
I = erlang:system_info(scheduler_id),
random(5).
random(I) when I > 10 ->
random(I+1);
random(I) ->
spawn(fun() -> random(I+1) end),
random(I+1).
此代码将Linux load跑到了10-20,取得了领先
Shell版
#!/bin/sh
for((i=0;i<10;i++));do
{
for((j=0;j<1000000000000;j++));do echo '1'>>1; done
}&
done
Ruby
ruby -e "require 'thread';t = Mutex.new;10.times {fork {10000000.times{t.synchronize {x=Time.now}}}}"
Java版
import java.io.*;
public class LoadTest {
public static void main(String[] args) throws IOException, InterruptedException {
int count = 1000;
for (int i = 0; i < count; i++) {
final Thread t = new Thread(new Runnable() {
public void run() {
try {
while (true) {
RandomAccessFile file = new RandomAccessFile("/tmp/test.bin", "rw");
file.seek(1024 * 1024 * 500);
file.write(1);
file.close();
}
} catch (IOException e) {
}
}
});
t.start();
}
Thread.currentThread().join();
}
}
C语言版
void main () {
int i=0;
for (i = 0; i < 1000; i++) {
if (fork () > 0) {
continue;
}
while (1) ;
}
getchar();
}
此版本远远超过了上面的Erlang版本,将load拉到1000+
Java版本2
public class Test {
public static void main(String[] args) {
for (int i = 0; i < 1000; i++) {
new Thread() {
@Override
public void run() {
while (true) ;
}
}.start();
}
}
}
此版本和上面C版本效果类似
部分讨论:
不对呀,这个方法以前不行
CentOS 6吧[惊讶]
CentOS 5
有几个版本有bug,cpu的hz拿的不对,load特别低,7就好了[坏笑]
Java版本3
写两类线程,一类进行lockObject wait, 一类进行lockObject notifyall。 cpu上下文切换消耗 竞争激烈。Load能很高。
public class LoadHighDemo {
public static void main(String[] args) throws Exception {
LoadHighDemo demo = new LoadHighDemo();
demo.runTest();
}
private void runTest() throws Exception {
Object[] locks = new Object[5000];
for (int i = 0; i < 5000; i++) {
locks[i] = new Object();
new Thread(new WaitTask(locks[i])).start();
new Thread(new NotifyTask(locks[i])).start();
}
}
class WaitTask implements Runnable {
private Object lockObject = null;
public WaitTask(Object obj) {
lockObject = obj;
}
public void run() {
while (true) {
try {
synchronized (lockObject) {
lockObject.wait(new java.util.Random().nextInt(10));
}
} catch (Exception e) {;
}
}
}
}
class NotifyTask implements Runnable {
private Object lockObject = null;
public NotifyTask(Object obj) {
lockObject = obj;
}
public void run() {
while (true) {
synchronized (lockObject) {
lockObject.notifyAll();
}
try {
Thread.sleep(new java.util.Random().nextInt(5));
} catch (InterruptedException e) {
}
}
}
}
}
上物理机把5000个线程改成更多,如50000也行。
直接while true改5000应该能更多……
我的应该能一直上涨, load 1000, 2000, 3000
可以试试parkNanos(1)
刚才卡了。。。
看来不能在本机上跑
Python版
把5分钟 load avg 稳定在1024了
在本群感到了一种情怀。。。
#!/usr/bin/env python
import os
import sys
import time
def load_add_1():
time.sleep(30)
fd=os.open("test.txt",os.O_CREAT|os.O_RDWR|os.O_SYNC, 0644)
for i in xrange(10000*100):
os.write(fd," "*100)
sys.exit(0)
for i in xrange(8192):
if os.fork() == 0:
load_add_1()
此版本将load跑到8192
C语言版本2
https://gist.github.com/hongqn/37cdfde04d0c5a03fede
#include <unistd.h>
#include <stdio.h>
#define LOAD 16384
int main() {
int i;
char s[256];
for (i=0; i<LOAD; i++) {
if (vfork()) {
return 0;
}
}
scanf("%s", s);
return 0;
}
macbook 上 virtualbox 里一个 2G mem 单 core cpu 的虚机就可以轻松达到16,000
这个的原理是通过 vfork 产生指定个数的 D 状态进程,从而提高 load
Vfork() differs from fork in that the child borrows the parent’s memory and thread of control until a call to execve(2) or an exit (either by a call to exit(2) or abnormally.) The parent process is suspended while the child is using its resources.
vfork 的子进程只要不 execve 或者退出,父进程就一直挂着(在D状态)。这里就是让最后一个子进程用 scanf 等输入
通过以上题目,你是看到了热闹,还是看到了门道?