转载

Linux Load编程竞赛

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 等输入

通过以上题目,你是看到了热闹,还是看到了门道?

正文到此结束
Loading...