def hello
Thread.new{
5.times {
sleep(1)
puts "thread.."
}
}##怎样让该线程独立运行,即在hello执行完毕后不会影响该线程的运行
sleep(2)
puts "hello exit!"
end
hello
## 执行结果
# thread...
# hello exit!
#预期结果是输出5次thread..
目的:hello 运行结束后,puts "thread.."那个线程还在运行 (后台运行也可以),两个线程是互相独立的。也就是说创建出来的线程不会影响原来的线程,原来的线程也不会影响创建出来的线程。
下面是 java 的实现:
public class TestThread {
public static void main(String[] args) {
TestThread ts = new TestThread();
Thread myThread = ts.new MyThead(100);
myThread.start();
System.out.println("main");
}
public class MyThead extends Thread {
private long sleepTime;
public MyThead (long sleepTime) {
this.sleepTime = sleepTime;
}
public void run() {
for (int i = 0 ; i < 10; i++) {
System.out.println(this.getName() + "\t----- " + i + " -----");
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
运行结果:
main #main线程退出
Thread-0 ----- 0 ----- #main中创建出来的线程继续运行
Thread-0 ----- 1 -----
Thread-0 ----- 2 -----
Thread-0 ----- 3 -----
Thread-0 ----- 4 -----
Thread-0 ----- 5 -----
Thread-0 ----- 6 -----
Thread-0 ----- 7 -----
Thread-0 ----- 8 -----
Thread-0 ----- 9 -----
就是想让一个线程马上返回,另一个线程继续执行任务
#5 楼 @zhenjunluo 你这种情况是:子线程还没执行完毕,主线程已经退出。Ruby 的线程有点像 Java 的守护线程,主线程执行完毕所有的子线程都会销毁,所以如果要等待子线程执行完毕需要在程序出口之前调用 join 阻塞主线程
你需要的是 process,不是 thread http://stackoverflow.com/questions/5449617/background-daemon-process
#4 楼 @zhenjunluo hello 执行之后,主进程如果不 thread.join 就会结束,那所有线程都会结束 线程就是这样的,你要达到目的要么 thread.join 要么 fork
@zhenjunluo 其实是两个问题:
public class TestThread {
public static void main(String[] args) {
TestThread ts = new TestThread();
Thread myThread = ts.new MyThead(100);
myThread.start();
System.out.println("main");
}
public class MyThead extends Thread {
private long sleepTime;
public MyThead (long sleepTime) {
this.sleepTime = sleepTime;
}
public void run() {
for (int i = 0 ; i < 10; i++) {
System.out.println(this.getName() + "\t----- " + i + " -----");
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
运行结果:
main
Thread-0 ----- 0 -----
Thread-0 ----- 1 -----
Thread-0 ----- 2 -----
Thread-0 ----- 3 -----
Thread-0 ----- 4 -----
Thread-0 ----- 5 -----
Thread-0 ----- 6 -----
Thread-0 ----- 7 -----
Thread-0 ----- 8 -----
Thread-0 ----- 9 -----
这是 java 中的实现
@zhenjunluo 可能你没看明白楼上说的,我把最后代码弄好给你看
def hello
thread = Thread.new{
5.times {
sleep(1)
puts "thread.."
}
}
sleep 2
puts "hello exit!"
thread
end
thread = hello()
thread.join # 主线程结束后, 程序就结束了, 如果要等待其他线程结束后再结束主线程, 要调用 join
如果你在一个长期执行的程序里创建 thread, 例如 rails 里,就不需要 thread.join
了
#19 楼 @zhenjunluo 你原来的程序已经创建了线程并且平行于主线程运行了,问题是 ruby 线程和 java 线程不一样:java 进程会等待所有线程结束才结束,ruby 主线程结束了进程就结束了,进程结束时所有其他线程都一起完蛋。这就是为什么这个 hello 程序里看不到想要的效果,为了看到效果,别人才建议你用 thread.join
去等待 hello()
创建的线程结束。
但如果你一开始就说明白是 rails 里创建的线程,那又是另一回事了。rails 的主线程一直存在,不用调用 thread.join
去等待 hello()
创建的线程结束。
#15 楼 @zhenjunluo java 能这样是因为 jvm 会等待所有的线程结束,也就是 jvm 帮你做了 join。ruby 没有,所以你要自己调用
#19 楼 @zhenjunluo 真心建议不要这么做,不知道 Ruby 怎么新建线程和切换上下文,不过代价应该是不会少,你这样用绝对死得飞快。建议像@reus 说的,采用任务队列。 话说,好像没看到 ruby vm 相关的书籍呢,现在都是用 jvm 原理来想当然的胡扯 = =
#23 楼 @reus #24 楼 @saiga 网上是这么说的,ruby 解释器一退出,就会杀死所有的线程,不管它们的死活。如果采用任务队列的话,那么会存在延时,也就是说这个任务可能会等待几秒中然后才会执行。
我目前的使用场景是,前端发来一个请求,我要马上返回,让它把页面渲染出来,同时有线程在后面获取数据,时间有时会很长,10s 以上,如果顺序执行,那么在最糟糕的情况下,这个页面渲染出来需要很长时间;如果等页面渲染完在发请求来获取数据,这样又慢了一段时间! 目前我使用 ruby 的 drb 库来实现,在后台启动一个 drb server,在 action 中发一个请求给 drb server,创建线程的事情就交给它了,action 也可以马上返回。这样的缺点是如果并发大的话,创建的线程就会很多
不知到你们有没有好的方法,或者能够保证队列中的任务立马运行
#26 楼 @zhenjunluo 用 thread pool 替代 drb,这样不会动态创建线程,参考:http://burgestrand.se/articles/quick-and-simple-ruby-thread-pool.html
@zhenjunluo 搞太复杂了!页面的咚咚可以静态化或者提前缓存好,请求和加载数据的活交给 js 吧,ruby 只负责把处理完的结果通过 json 反馈给 js,这些线程、进程的复杂事情都交给 web server 和 app server 去干,你的线程处理得再好也不如一个成熟的 web server 能力强。
@zhenjunluo 简单说,就是把 rails 搞成一个 rails-api,页面展现别揉在 rails 里面,把页面前端做成 webapps,今后可以直接换成 iOS/Android 等 Native Apps,后端基本不用改动。
rails 是永远运行的,所以加个 loop do 吧 :
hello
loop do
sleep 1
end
或这样:
hello
sleep 9999999999999999
#33 楼 @zhenjunluo 你26#都说缺点是并发大的时候线程会多,这个本来就是矛盾的,既然队列有延迟就代表任务没执行完,这种情况如果是线程肯定也会创建很多。折中下,就是耗时不是很久的任务多分配几个worker尽量保证速度,很慢才能执行完的任务就让他慢下去。。
#36 楼 @zhenjunluo 不需要开源呀,比如 rails 里面只做 api,views 部分不放在 rails 里面,单独写,只包含 HTML/CSS/JS