tokuhirom's blog.

'; DROP DATABASE database();

summary of cons/pros about ithreads/coro/fork(2)

rafl wishes gfuji and tokuhirom would blog in english

などといわれたので、ためしに英語で1エントリだけかいてみるよ。

Perl5 has some ways for concurrent programming.This article is research summary for that tools.

summary

coro ithreads fork(2)
speed for creating new one fast slow fast
memory footprint great too bad great*1
ease to use great bad bad
cpan friendly? good bad great
stability good bad great
works well on multiple CPUs? bad bad great
easy to communicate one another? great good bad
black magic !!! - -

detail

ithreads
  • ithreads is a port of win32 process emulation for UNIX.
  • ithreads uses a lot of memory
    • This cause swap out...
    • Cannot create a lot of threads
  • ithreads' new thread creation is very slow
    • very very slow
  • a lot of CPAN modules are not ithreads safe.
  • ithreads enabled perl is makes 0.1x slower(see http://d.hatena.ne.jp/gfx/20090629/1246262660)
  • Sharing variable between ithreads is never easy.
    • blessed objects, etc...
  • ithreads dump core too often
fork(2)
  • save memories by Copy on Write mechanism(on *nix systems)
  • forked processes are very stable and CPAN friendly =)
  • forked processes works on multiple CPUs.This is good for modern servers.
  • Programming management forked processes is hard.
    • I don't want to fork Apache!
    • I hate zombie process...
Coro
  • Coro is black magic.
  • Coro's coroutine is very lightweight!
  • Coro doesn't use a lot of memory.
  • Programming with Coro is very easy.
  • Very easy to communicate between coros.

Conclusion

  • I don't want to use ithreads.
  • fork(2) is good enough for most cases
    • CPU intensive problems should use fork(2)
  • Coro is good for I/O intensive problems
    • like a crawler
  • Coro is good for web applications
    • send a queries for RDBMS concurrently
    • Coro can pass the result of queries easily =)
    • etc.

*1:by Copy on Write

detect xss in TT

昔書いた TT の中にある XSS を発見するスクリプトを発見したのでサルベージしとくます。

#!/usr/local/bin/ruby

ARGV.each {|fname|
        File.read(fname).scan(/\[%-?(.+?)-?%\]/i) {|m|
                body = $1
                unless %w(SWITCH CASE USE PROCESS BLOCK INCLUDE ELSE ELSIF FOR IF END UNLESS SET).index($1.split[0])
                        next if $1.split.index('html')
                        printf "%s : %s\n", fname, body
                end
        }
}