• Feeds

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

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

     

    ArchSummit 2015深圳见闻

    这几天参加了ArchSummit深圳全球架构师峰会,AS深圳的地点一直都选在大梅沙,这次大会在海湾大酒店举行。

    两天的ArchSummit大会日程比较紧凑,再加上大多数时候有6个专题在并行,因此每个人能够真正去听的课程不会太多。如果刚好碰到朋友多聊几句,能真正听的场次就更少了。

    第一场是LinkedIn一个技术经理演讲Big Data Story,数据的重要性在各行各业已经体现出来,关键是每个领域需要自己去思考如何更好的挖掘及应用数据。

    下午选了一个在线教育的专场听了几个分享,基本都是围绕线教育领域的大数据应用。由于对在线教育缺少了解,不知是专题选题的缘故还是在线教育的门槛确实提高了,听到的几个案例都是比较偏大数据算法。猿题库研究部总监邓澍军介绍了拍照搜题功能中Deep Learning技术的应用,从介绍的案例来看,识别的门槛还是比较高,不知道与业界其他一大批搜题领域的创业公司技术实力是什么级别的差异。

    第二天主题也比较丰富,印象比较深的是由微信朋友圈负责人陈明的分享。朋友圈后端目前只有3个工程师,讲师以Instagram及whatsapp为例,认为目前小团队存在一定程度的优势。朋友圈的技术特色主要有分布式多机房的设计,以及由多机房架构带来的异地数据一致性问题的产生,微信采用的策略是因果一致性,主要目的是让同一个图片下不同机房回复的用户评论保证因果次序。(可参考分享的ppt进一步了解)

    有不少人参会多的人会觉得参加几次大会后收获越来越小,在某种程度,也可能跟装满水的杯子道理相似,工作多年,形成了自己的解决问题的经验及思维定势,虽然别的方法更好,但从心理的角度,可能总觉得不如自己原先的方法。

    两天的会议开完后,会议在大梅沙海边的游艇会上有一个party,运营ArchSummit(包括InfoQ)的极客邦科技的老板-Kevin Huo同学给大家组织了精彩的活动,也在演讲中讲述了他一向的观点,技术人员在社会上应该得到最好的对待。因此特地选择了在海边的游艇会,看乐队的演出,吃着烧烤,喝着啤酒,聊聊技术与人生。

    PS: ArchSummit所有slides都已经放出,可以在stu.org官网获得。

    黑客马拉松需要什么样的创新项目?

    hackathon go
    一场黑客马拉松项目,大家会首先选择那些业界做得不够完善、或者有较大潜在价值的领域。比如最近举行的Go & Docker Hackathon,参赛人员会首选Docker领域的服务发现、服务调度等领域。

    Docker是一种软件打包及运行的技术,其主要思想是将软件打包成一个image并可以到任意的机器运行,运行时候已经被打包的可执行文件被隔离在一个叫容器的沙箱里运行,并独立于系统其他服务,安全性及资源占用方面都得到了有效控制。Docker软件以及大部分Docker生态圈的软件是由Google的Go语言(也称为为Golang)编写。

    但上面提到这些Docker领域的功能需求和实现都较复杂,完成一项功能费事费力,在短时间尤其是一天的Hackathon期间内,很难较好的完成。反而是找一些技术实现简单的领域,解决一个较小的需求,不但可以快速实现,并可以有机会将体验做得更好。让项目在一个很小但又经常使用的点上打动用户,得到用户的关注及认可。比如这次就有一支队伍完成了一个Dockerfile(生成Docker镜像的配置文件)的编辑器,并且进一步可以将用户在测试环境的的操作录制下来,自动构造Dockerfile。虽然技术实现很简单,但是对很多Docker用户会带来便利。

    很多公司在选择创业项目的时候也会碰到如此的情况,如果选择了一个技术实现复杂的领域,考虑到功能的完整性,早期的开发周期就会变得不可控。创业公司通常希望每个月都有新的产品迭代,但复杂领域的开发,预期1-3个月的项目通常会拖到半年以上,这无疑是增加了公司运营的风险。

    Docker目前在实际环境中主要还是用在管理云平台上的服务,但Docker的这种隔离运行的思想也可以应用在更多领域,比如参赛中应用在硬件控制、可插拔的开放平台等领域的设想。

    黑客精神的一个重要点是程序员通过自己的编程打破已有的软件功能使用方式,给程序员自身及其他使用软件的用户带来自由及便利。参赛作品中比较能触动这一点的是挑战Siri的封闭性的一个项目,他设想通过一个个外接的容器能将智能做得更扩展,延伸到生活各方各面。有点类似微信的连接一切的概念,不过连接之后HUB不是微信,而是一个类似Siri这样的入口。

    从这个角度,大部分我观察到的程序员思想还都比较禁锢,一方面是从小缺少创新(或者改变)的氛围及引导,在被设计的道路上循规蹈矩的长大,学习成绩好就是一个好孩子。工作后比较正常的做法也是每天接受分配的任务,完成得好就是一个靠谱的成员;打破常规的改变的成本过高,也被视为不那么正常的孩子。程序员即使换工作,也经常落在在薪酬、Title等因素的考量上,较少有动力去首先考虑那些通过技术来改变一个领域的事情上去。