<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tim[后端技术] &#187; Linux</title>
	<atom:link href="http://timyang.net/category/linux/feed/" rel="self" type="application/rss+xml" />
	<link>http://timyang.net</link>
	<description>Tim&#039;s blog, 关于后端架构、互联网技术、分布式、大型网络应用、NoSQL、Key Value等</description>
	<lastBuildDate>Mon, 26 Jul 2010 15:32:05 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>利用Gearman来实现远程监控与管理</title>
		<link>http://timyang.net/linux/gearman-monitor/</link>
		<comments>http://timyang.net/linux/gearman-monitor/#comments</comments>
		<pubDate>Wed, 26 Aug 2009 12:57:09 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[gearman]]></category>

		<guid isPermaLink="false">http://timyang.net/?p=392</guid>
		<description><![CDATA[
Gearman是一个分发任务的程序框架，可以用在各种场合，与Hadoop相比，Gearman更偏向于任务分发功能。它的任务分布非常简单，简单得可以只需要用脚本即可完成。Gearman最初用于LiveJournal的图片resize功能，由于图片resize需要消耗大量计算资源，因此需要调度到后端多台服务器执行，完成任务之后返回前端再呈现到界面。

Gearman分布式任务实现原理上只用到2个字段，function name和data。function name即任务名称，由client传给job server, job server根据function name选择合适的worker节点来执行。data通常为执行任务所需的自定义的内容，比如简单的做法可以把需要执行的脚本当成data即可(当然要注意其中的安全防范)。如果有多个worker可以处理同一个function name, 则job server会自动分配一个。当用于远程监控场景时，我们可以让每个worker注册成不同的业务名称，以达到方便控制每台worker节点的目的。
下面介绍Gearman实践中可用于多服务器管理的一些小功能，如果你的服务器有多台，重复执行命令过于繁琐，那可以借助下面一些脚本来完成一些有趣的功能。比如要实时看到所有服务器上的 netstat -nat &#124; grep 80, 按下面步骤搭好环境之后，只需要几行脚本代码即可实现。
1. 安装gearman
最早的gearman是perl版的，由于国内开发人员对perl熟悉的不多，所以推荐安装C版本
 http://gearman.org/index.php?id=download
解开后 ./configure; make; make install 即可
2. 启动 job server
cd sbin; ./gearmand -d
3. 到 worker 节点启动 worker
先按步骤1在worker机上安装 gearman, 然后创建一个执行worker的python脚本。
#!/usr/bin/env python
import os

def main():
    cmd = raw_input()
    print os.popen(cmd).read()

if __name__ == "__main__":
    [...]]]></description>
			<content:encoded><![CDATA[<div class="level2">
<p><a href="http://gearman.org/">Gearman</a>是一个分发任务的程序框架，可以用在各种场合，与<a href="http://hadoop.apache.org/">Hadoop</a>相比，Gearman更偏向于任务分发功能。它的任务分布非常简单，简单得可以只需要用脚本即可完成。Gearman最初用于LiveJournal的图片resize功能，由于图片resize需要消耗大量计算资源，因此需要调度到后端多台服务器执行，完成任务之后返回前端再呈现到界面。</div>
<p><img class="alignnone size-full wp-image-394" title="gearman" src="http://timyang.net/blog/wp-content/uploads/2009/08/gearman.png" alt="gearman" width="489" height="457" /></p>
<p>Gearman分布式任务实现原理上只用到2个字段，function name和data。function name即任务名称，由client传给job server, job server根据function name选择合适的worker节点来执行。data通常为执行任务所需的自定义的内容，比如简单的做法可以把需要执行的脚本当成data即可(当然要注意其中的安全防范)。如果有多个worker可以处理同一个function name, 则job server会自动分配一个。当用于远程监控场景时，我们可以让每个worker注册成不同的业务名称，以达到方便控制每台worker节点的目的。</p>
<p>下面介绍Gearman实践中可用于多服务器管理的一些小功能，如果你的服务器有多台，重复执行命令过于繁琐，那可以借助下面一些脚本来完成一些有趣的功能。比如要实时看到所有服务器上的 netstat -nat | grep 80, 按下面步骤搭好环境之后，只需要几行脚本代码即可实现。</p>
<p><strong>1. 安装gearman</strong><br />
最早的gearman是perl版的，由于国内开发人员对perl熟悉的不多，所以推荐安装C版本<br />
<a href="http://gearman.org/index.php?id=download"> http://gearman.org/index.php?id=download</a><br />
解开后 ./configure; make; make install 即可</p>
<p><strong>2. 启动 job server</strong><br />
cd sbin; ./gearmand -d</p>
<p><strong>3. 到 worker 节点启动 worker</strong></p>
<p>先按步骤1在worker机上安装 gearman, 然后创建一个执行worker的python脚本。</p>
<pre>#!/usr/bin/env python
import os

def main():
    cmd = raw_input()
    print os.popen(cmd).read()

if __name__ == "__main__":
    main()</pre>
<p>cd bin; ./gearman -w -h &lt;job_server_ip&gt; -f server1 &#8212; ./monitor.py</p>
<p><strong>4. 通过远程 web 管理</strong><br />
JSP示例：</p>
<pre>&lt;%@ page language="java" import="java.util.*,java.util.concurrent.*,
org.gearman.client.*,org.gearman.common.*"%&gt;&lt;%!
        private static String host = "192.168.1.1";
        private static int port = 4730;
        public String testGearman(String func, String data) {
                byte[] input = data.getBytes();
                String uniqueId = null;

                GearmanJobServerConnection conn =
                    new GearmanNIOJobServerConnection(host, port);
                GearmanClient client = new GearmanClientImpl();
                client.addJobServer(conn);
                GearmanJob job = GearmanJobImpl.createJob(func, input, uniqueId);
                Future&lt;GearmanJobResult&gt; f = client.submit(job);
                GearmanJobResult jr = null;
                String result = null;
                try {
                        jr = f.get(3, TimeUnit.SECONDS);
                        result = new String(jr.getResults());
                } catch (Exception e) {
                        result = e.getMessage();
                }

                client.shutdown();
                return result;
        }
%&gt;&lt;%
out.println(testGearman("test", "netstat -nat | grep 80");
%&gt;</pre>
<p>PHP示例：</p>
<pre># Create our client object.
$client= new GearmanClient();

# Add default server (localhost).
$client-&gt;addServer();

echo "Sending job\n";

# Send reverse job
$result = $client-&gt;do("server1", "netstat -nat | grep 80");
if ($result)
  echo "Success: $result\n";</pre>
Similar Posts:<ul><li><a href="http://timyang.net/data/mcdb-tt-redis/" rel="bookmark" title="August 11, 2009">MemcacheDB, Tokyo Tyrant, Redis performance test</a></li>

<li><a href="http://timyang.net/python/python-thread-socket-server/" rel="bookmark" title="March 8, 2009">Python thread socket server</a></li>

<li><a href="http://timyang.net/python/python-rest/" rel="bookmark" title="February 12, 2009">用Python实现CRUD功能REST服务</a></li>

<li><a href="http://timyang.net/programming/thrift-protocol-buffers-performance-java/" rel="bookmark" title="April 2, 2009">Thrift and Protocol Buffers performance in Java</a></li>

<li><a href="http://timyang.net/programming/c-erlang-java-performance/" rel="bookmark" title="November 11, 2009">C, Erlang, Java and Go Web Server performance test</a></li>
</ul><!-- Similar Posts took 14.338 ms -->]]></content:encoded>
			<wfw:commentRss>http://timyang.net/linux/gearman-monitor/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>谈Linux内核定时器</title>
		<link>http://timyang.net/linux/linux-timer-tick/</link>
		<comments>http://timyang.net/linux/linux-timer-tick/#comments</comments>
		<pubDate>Mon, 18 May 2009 12:10:41 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[kernel]]></category>
		<category><![CDATA[timer]]></category>

		<guid isPermaLink="false">http://timyang.net/?p=182</guid>
		<description><![CDATA[看了3个周末的Linux内核，包括前两周总结的进程与线程，锁与同步。当时研究这个的原因是因为某个程序CPU context switch过高。不过到现在相关的背景知识也了解了，问题也早已经解决了，所以暂时也没有进一步的兴趣驱动去研究内核了，这里是终结篇。:)
在应用程序运行的时候，特别是抢占式的操作系统里面，内核怎么样取得控制权？这依赖硬件支持的系统定时器来实现。内核中有非常多的功能由定时器触发。系统定时器以固定的频率触发，这个频率称为tick rate(HZ)，每个触发周期的时间叫做tick, 它等于1/HZ秒。触发后系统会转到内核相应的handler去处理。
在系统定时器中断时候内核需要做以下事情

更新uptime, time of day, resource及处理器使用状态
检查多处理器是否负载均衡
检查当前进程是否timeslice是否用完，如果用完则重新分配下阶段计划(reschedule)
运行应用程序自定义的定时器(dynamic timers)

了解了tick rate之后才能比较好理解为什么sleep(), timer等API声称都不是提供精确的时间，因为cpu一个任务timeslice没运行完，系统是不会马上切换到这些dynamic timer的进程的。
Linux 2.5以上将tick从100改成1000，相当于系统时钟从10ms变成每1ms要中断一次，当时也引起较大的争议。
改成1000的优点有：

系统时钟精度更高更准确。
系统调用如poll(), select() 等依赖系统时钟的调用性能得到很大改善。
内核实时运行指标如资源占用，uptime更准确。
抢占式机制更精确。

缺点：
我们知道定时器频繁被触发必将会增加开销，降低throughput。这是很多人反对改成1000的理由。原理上它在CPU的时间中断上将会增加10倍的开销。但由于现代CPU硬件速度的变快。大家也逐渐认可了新的调整不会给整体性能带来大的影响。如果在意这一点的可以重新编译内核， 将&#60;asm/param.h&#62;中HZ的值由1000降低。目前可以接受的值有100,500和1000。
Linux 2.6.21 又增加了一种叫dyntick的技术，dyntick就是在系统空闲的时候，彻底停止时间中断， 避免cpu空转，它会带来节能方面的好处。详情可参看Clockevents and dyntick。这是个新的技术，一般的书上都没来得及写进去。
比较感兴趣的后续课题是virtualization系统中的timer实现。
Similar Posts:了解Linux的进程与线程

Lua coroutine vs Java wait/notify

多服务器通讯层应该如何设计—一次code review小记

了解Linux的锁与同步

高性能网站经验-读杨建的Blog有感
]]></description>
			<content:encoded><![CDATA[<p>看了3个周末的Linux内核，包括前两周总结的<a href="http://timyang.net/linux/linux-process/">进程与线程</a>，<a href="http://timyang.net/programming/linux-synchronization-lock/">锁与同步</a>。当时研究这个的原因是因为<a href="http://twitter.com/xmpp/status/1635132615" target="_blank">某个程序CPU context switch过高</a>。不过到现在相关的背景知识也了解了，问题也早已经解决了，所以暂时也没有进一步的兴趣驱动去研究内核了，这里是终结篇。:)</p>
<p>在应用程序运行的时候，特别是抢占式的操作系统里面，内核怎么样取得控制权？这依赖硬件支持的系统定时器来实现。内核中有非常多的功能由定时器触发。系统定时器以固定的频率触发，这个频率称为tick rate(HZ)，每个触发周期的时间叫做tick, 它等于1/HZ秒。触发后系统会转到内核相应的handler去处理。</p>
<p>在系统定时器中断时候内核需要做以下事情</p>
<ul>
<li>更新uptime, time of day, resource及处理器使用状态</li>
<li>检查多处理器是否负载均衡</li>
<li>检查当前进程是否timeslice是否用完，如果用完则重新分配下阶段计划(reschedule)</li>
<li>运行应用程序自定义的定时器(dynamic timers)</li>
</ul>
<p>了解了tick rate之后才能比较好理解为什么sleep(), timer等API声称都不是提供精确的时间，因为cpu一个任务timeslice没运行完，系统是不会马上切换到这些dynamic timer的进程的。</p>
<p>Linux 2.5以上将tick从100改成1000，相当于系统时钟从10ms变成每1ms要中断一次，当时也引起较大的争议。</p>
<p>改成1000的优点有：</p>
<ul>
<li>系统时钟精度更高更准确。</li>
<li>系统调用如poll(), select() 等依赖系统时钟的调用性能得到很大改善。</li>
<li>内核实时运行指标如资源占用，uptime更准确。</li>
<li>抢占式机制更精确。</li>
</ul>
<p>缺点：<br />
我们知道定时器频繁被触发必将会增加开销，降低throughput。这是很多人反对改成1000的理由。原理上它在CPU的时间中断上将会增加10倍的开销。但由于现代CPU硬件速度的变快。大家也逐渐认可了新的调整不会给整体性能带来大的影响。如果在意这一点的可以重新编译内核， 将&lt;asm/param.h&gt;中HZ的值由1000降低。目前可以接受的值有100,500和1000。</p>
<p>Linux 2.6.21 又增加了一种叫dyntick的技术，dyntick就是在系统空闲的时候，彻底停止时间中断， 避免cpu空转，它会带来节能方面的好处。详情可参看<a href="http://lwn.net/Articles/223185/" target="_blank">Clockevents and dyntick</a>。这是个新的技术，一般的书上都没来得及写进去。</p>
<p>比较感兴趣的后续课题是virtualization系统中的timer实现。</p>
Similar Posts:<ul><li><a href="http://timyang.net/linux/linux-process/" rel="bookmark" title="May 3, 2009">了解Linux的进程与线程</a></li>

<li><a href="http://timyang.net/lua/lua-coroutine-vs-java-wait-notify/" rel="bookmark" title="April 27, 2009">Lua coroutine vs Java wait/notify</a></li>

<li><a href="http://timyang.net/architecture/communication-code-review/" rel="bookmark" title="May 22, 2009">多服务器通讯层应该如何设计—一次code review小记</a></li>

<li><a href="http://timyang.net/programming/linux-synchronization-lock/" rel="bookmark" title="May 10, 2009">了解Linux的锁与同步</a></li>

<li><a href="http://timyang.net/architecture/yangjian-web-server/" rel="bookmark" title="April 28, 2009">高性能网站经验-读杨建的Blog有感</a></li>
</ul><!-- Similar Posts took 16.647 ms -->]]></content:encoded>
			<wfw:commentRss>http://timyang.net/linux/linux-timer-tick/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>了解Linux的进程与线程</title>
		<link>http://timyang.net/linux/linux-process/</link>
		<comments>http://timyang.net/linux/linux-process/#comments</comments>
		<pubDate>Sun, 03 May 2009 10:48:58 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[thread]]></category>

		<guid isPermaLink="false">http://timyang.net/linux/%e4%ba%86%e8%a7%a3linux%e7%9a%84%e8%bf%9b%e7%a8%8b%e4%b8%8e%e7%ba%bf%e7%a8%8b/</guid>
		<description><![CDATA[上周碰到部署在真实服务器上某个应用CPU占用过高的问题，虽然经过tuning, 问题貌似已经解决，但我对tuning的方式只是基于大胆的假设并最终生效了。我更希望更多的求证一下程序背后CPU及OS kernel当时的运作机制。所以我读了一些Linux内核设计与实现及其他一些相关资料，对Linux process的机制与切换有了更多一些体会。本文尽可能条理一点，但由于牵涉点较多，同时自己可能觉得某些点有记录的价值，因此文字可能会零散。

进程状态

Linux进程的状态比较容易理解，值得注意的是 UNINTERRUPTIBLE 及 ZOMBIE
TASK_RUNNING
TASK_INTERRUPTIBLE
TASK_UNINTERRUPTIBLE 此时进程不接收信号，这就是为什么有时候kill一个繁忙的进程没有响应。
TASK_ZOMBIE 我们经常 kill -9 pid 之后运行ps会发现被kill的进程仍然存在，状态为 zombie。zombie的进程实际上已经结束，占用的资源也已经释放，仅由于kernel的相关进程描述符还未释放。
TASK_STOPPED

Kernel space and user space

Kernel space是供内核，设备驱动运行的内存区域。user space是供普通应用程序运行的区域。每一个进程都运行在自己的虚拟内存区域，不能访问其他进程的内存空间。普通进程不能访问kernel space, 只能通过系统调用来间接进行。当系统内存比较紧张时，非当前运行进程user space可能会被swap到磁盘。
使用命令 pmap -x &#60;pid&#62; 可以查看进程的内存占用信息； lsof -a -p &#60;pid&#62; 可以查看一个进程打开的文件信息。ps -Lf &#60;pid&#62; 可以查看进程的线程数。
另外procfs也是一个分析进程结构的好地方。procfs是一个虚拟的文件系统，它把系统中正在运行的进程都显现在/proc/&#60;pid&#62;目录下。

进程创建

进程创建通常调用fork实现。创建后子进程和父进程指向同一内存区域，仅当子进程有write发生时候，才会把改动的区域copy到子进程新的地址空间，这就是copy-on-write技术，它极大的提高了创建进程的速度。

Linux的线程实现

Linux线程是通过进程来实现。Linux kernel为进程创建提供一个clone()系统调用，clone的参数包括如 CLONE_VM, CLONE_FILES, CLONE_SIGHAND 等。通过clone()的参数，新创建的进程，也称为LWP(Lightweight process)与父进程共享内存空间，文件句柄，信号处理等，从而达到创建线程相同的目的。
Linux 2.6的线程库叫NPTL(Native POSIX Thread Library)。POSIX thread(pthread)是一个编程规范，通过此规范开发的多线程程序具有良好的跨平台特性。尽管是基于进程的实现，但新版的NPTL创建线程的效率非常高。一些测试显示，基于NPTL的内核创建10万个线程只需要2秒，而没有NPTL支持的内核则需要长达15分钟。
在Linux 2.6之前，Linux kernel并没有真正的thread支持，一些thread library都是在clone()基础上的一些基于user space的封装，因此通常在信号处理、进程调度(每个进程需要一个额外的调度线程)及多线程之间同步共享资源等方面存在一定问题。为了解决这些问题，当年IBM曾经开发一套NGPT(Next Generation POSIX Threads), 效率比 LinuxThreads有明显改进，但由于NPTL的推出，NGPT也完成了相关的历史使命并停止了开发。
NPTL的实现是在kernel增加了futex(fast [...]]]></description>
			<content:encoded><![CDATA[<p>上周碰到部署在真实服务器上某个应用<a href="http://twitter.com/xmpp/statuses/1635132615" target="_blank">CPU占用过高</a>的问题，虽然经过tuning, 问题貌似已经解决，但我对tuning的方式只是基于大胆的假设并最终生效了。我更希望更多的求证一下程序背后CPU及OS kernel当时的运作机制。所以我读了一些<a href="http://www.douban.com/subject/1446021/" target="_blank">Linux内核设计与实现</a>及其他一些相关资料，对Linux process的机制与切换有了更多一些体会。本文尽可能条理一点，但由于牵涉点较多，同时自己可能觉得某些点有记录的价值，因此文字可能会零散。</p>
<ul>
<li>进程状态</li>
</ul>
<p>Linux进程的状态比较容易理解，值得注意的是 UNINTERRUPTIBLE 及 ZOMBIE</p>
<p>TASK_RUNNING<br />
TASK_INTERRUPTIBLE<br />
TASK_UNINTERRUPTIBLE 此时进程不接收信号，这就是为什么有时候kill一个繁忙的进程没有响应。<br />
TASK_ZOMBIE 我们经常 kill -9 pid 之后运行ps会发现被kill的进程仍然存在，状态为 zombie。zombie的进程实际上已经结束，占用的资源也已经释放，仅由于kernel的相关进程描述符还未释放。<br />
TASK_STOPPED</p>
<ul>
<li>Kernel space and user space</li>
</ul>
<p>Kernel space是供内核，设备驱动运行的内存区域。user space是供普通应用程序运行的区域。每一个进程都运行在自己的虚拟内存区域，不能访问其他进程的内存空间。普通进程不能访问kernel space, 只能通过系统调用来间接进行。当系统内存比较紧张时，非当前运行进程user space可能会被swap到磁盘。</p>
<p>使用命令 pmap -x &lt;pid&gt; 可以查看进程的内存占用信息； lsof -a -p &lt;pid&gt; 可以查看一个进程打开的文件信息。ps -Lf &lt;pid&gt; 可以查看进程的线程数。</p>
<p>另外procfs也是一个分析进程结构的好地方。procfs是一个虚拟的文件系统，它把系统中正在运行的进程都显现在/proc/&lt;pid&gt;目录下。</p>
<ul>
<li>进程创建</li>
</ul>
<p>进程创建通常调用fork实现。创建后子进程和父进程指向同一内存区域，仅当子进程有write发生时候，才会把改动的区域copy到子进程新的地址空间，这就是copy-on-write技术，它极大的提高了创建进程的速度。</p>
<ul>
<li>Linux的线程实现</li>
</ul>
<p>Linux线程是通过进程来实现。Linux kernel为进程创建提供一个clone()系统调用，clone的参数包括如 CLONE_VM, CLONE_FILES, CLONE_SIGHAND 等。通过clone()的参数，新创建的进程，也称为LWP(Lightweight process)与父进程共享内存空间，文件句柄，信号处理等，从而达到创建线程相同的目的。</p>
<p>Linux 2.6的线程库叫NPTL(Native POSIX Thread Library)。POSIX thread(pthread)是一个编程规范，通过此规范开发的多线程程序具有良好的跨平台特性。尽管是基于进程的实现，但新版的NPTL创建线程的效率非常高。一些测试显示，基于NPTL的内核创建10万个线程只需要2秒，而没有NPTL支持的内核则需要长达15分钟。</p>
<p>在Linux 2.6之前，Linux kernel并没有真正的thread支持，一些thread library都是在clone()基础上的一些基于user space的封装，因此通常在信号处理、进程调度(每个进程需要一个额外的调度线程)及多线程之间同步共享资源等方面存在一定问题。为了解决这些问题，当年IBM曾经开发一套NGPT(Next Generation POSIX Threads), 效率比 LinuxThreads有明显改进，但由于NPTL的推出，NGPT也完成了相关的历史使命并停止了开发。</p>
<p>NPTL的实现是在kernel增加了futex(fast userspace mutex)支持用于处理线程之间的sleep与wake。futex是一种高效的对共享资源互斥访问的算法。kernel在里面起仲裁作用，但通常都由进程自行完成。</p>
<p>NPTL是一个1&#215;1的线程模型，即一个线程对于一个操作系统的调度进程，优点是非常简单。而其他一些操作系统比如Solaris则是MxN的，M对应创建的线程数，N对应操作系统可以运行的实体。(N&lt;M)，优点是线程切换快，但实现稍复杂。</p>
<ul>
<li>信号</li>
</ul>
<p>进程接收信号有两种：同步和异步。同步信号比如SEGILL(非法访问), SIGSEGV(segmentation fault)等。发生此类信号之后，系统会立即转到内核陷阱处理程序，因此同步信号也称为陷阱。异步信号如kill, lwp_kill, sigsend等调用产生的都是，异步信号也称为中断。</p>
<p>kill &lt;pid&gt; 调用的是 SIGTERM, 此信号可以被捕获和忽略。</p>
<p>kill -9 &lt;pid&gt; 调用的是 SIGKILL, 杀掉进程，不能被捕获和忽略。</p>
<p>SIGHUP是在终端被断开时候调用，如果信号没有被处理，进程会终止。这就是为什么突然断网刚通过远程终端启动的进程都终止的原因。防止的方法是在启动的命令前加上 nohup 命令来忽略 SIGHUP信号。如 nohup ./startup.sh &amp;</p>
<p>很多应用程序通常捕获SIGHUP用来实现一些自定义特性，比如通过控制台传递信号让正在运行的程序重新加载配置文件，避免重启带来的停止服务的副作用。可惜的是，在JAVA中没法直接使用这一功能，SUN JVM没有官方的signal支持，尽管它已经可以实现，详情可参看<a href="http://jeremymanson.blogspot.com/2007/06/signals-and-java.html" target="_blank">Singals and Java</a>.</p>
<p>另外有个有趣的现象是 zombie 状态的进程 kill/kill -9 都没有任何作用，这是由于进程本身已经不存在，所以没有相应的进程来处理signal, zombie状态的进程只是kernel中的进程描述符及相关数据结构没有释放，但进程实体已经不存在了。<img class="zemanta-pixie-img" src="http://img.zemanta.com/pixy.gif?x-id=facfcc8c-3046-8e07-aa6b-9e048a5b3124" alt="" /></p>
<p>关于僵尸进程，也可参看下酷壳上的这篇<a href="http://cocre.com/?p=656" target="_blank">Linux 的僵尸(zombie)进程</a>，从程序的角度解释了相关原理。</p>
Similar Posts:<ul><li><a href="http://timyang.net/programming/linux-synchronization-lock/" rel="bookmark" title="May 10, 2009">了解Linux的锁与同步</a></li>

<li><a href="http://timyang.net/linux/linux-timer-tick/" rel="bookmark" title="May 18, 2009">谈Linux内核定时器</a></li>

<li><a href="http://timyang.net/architecture/game-backend/" rel="bookmark" title="December 25, 2008">陈杰谈网游服务器的后端技术</a></li>

<li><a href="http://timyang.net/programming/c-erlang-java-performance/" rel="bookmark" title="November 11, 2009">C, Erlang, Java and Go Web Server performance test</a></li>

<li><a href="http://timyang.net/lua/lua-coroutine/" rel="bookmark" title="April 26, 2009">Lua coroutine 不一样的多线程编程思路</a></li>
</ul><!-- Similar Posts took 16.870 ms -->]]></content:encoded>
			<wfw:commentRss>http://timyang.net/linux/linux-process/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
