import java.awt.Toolkit
import java.awt.event.AWTEventListener
import java.awt.event.KeyEvent
import javax.swing.JFrame
import javax.swing.JLabel
import javax.swing.JTextField
public class Test extends JFrame implements AWTEventListener{
JLabel infoLabel=new JLabel("请输入一个整数!")
JTextField resultField=new JTextField()
String num=""
public void init(){
setLayout(null)
setTitle("求数列和")
setSize(180,105)
infoLabel.setBounds(10, 10, 100, 30)
resultField.setBounds(10, 40, 150, 25)
setResizable(false)
setLocationRelativeTo(null)
resultField.setFocusable(false)
setDefaultCloseOperation(EXIT_ON_CLOSE)
Toolkit.getDefaultToolkit().addAWTEventListener(this, KeyEvent.KEY_EVENT_MASK)
add(infoLabel)
add(resultField)
setVisible(true)
}
public static void main(String[] args) {
new Test().init()
}
public void eventDispatched(AWTEvent e) {
KeyEvent keyEvent=(KeyEvent)e
if(keyEvent.getID()==KeyEvent.KEY_PRESSED){
int keycode=keyEvent.getKeyCode()
if(keycode==10){
if(!num.equals("")){
infoLabel.setText("\""+num+"\" 的数列和为:")
resultField.setText(""+sum(Integer.parseInt(num)))
num=""
}
}else if(keycode>=48 &&keycode<=57){
num+=(char)keycode
infoLabel.setText("当前输入:"+num)
resultField.setText("")
}else{
resultField.setText("输入错误,重新输入")
num=""
}
}
}
private int sum(int n){
int k=0
for(int i=1i<=ni++){
k+=i
}
return k
}
}
所以,有时候对进程进行实时监控,当发现进程挂掉时,立刻重新启动进程,也是一种可以救急的方式(当然这个只是一种临时救急,并不是根本解决方法)。实现方式:使用fork()创建子进程,子进程用于执行具体功能,主进程只是用于监控子进程,当主进程检测到子进程挂掉后,可以实现立即重新启动子进程。
子进程结束,系统会向主进程发送信号:SIGCHLD,主进程可以通过捕捉该信号,从而检测子进程已经不存在,进而继续下一步 *** 作。如果需要,主进程还可以获得子进程是为何退出的。
源代码例子:#include#include#include#include#include#include#includevoid process_exit(int s){exit(0)}void child_fun(){printf("child_fun. ppid %d\n",getppid())
char *st = NULL
strcpy(st, "123")}void fork_child(){pid_t child_process
int status
int signal_num
wait(&status)//等待子进程中断或终止,释放子进程资源,否则死掉的子进程会变成僵尸进程
//如果子进程是由于某种信号退出的,捕获该信号
if(WIFSIGNALED(status))
signal_num = WTERMSIG(status)
child_process = fork()
if(child_process == 0){printf("fork new child process.\n")
child_fun()}}int main(){pid_t child_processint i = 0while(1){printf("fork new process.\n")
child_process = fork()
if(child_process >0){while(1){//捕获子进程结束信号
signal(SIGCHLD, fork_child)
signal(SIGTERM, process_exit)
pause()//主进程休眠,当有信号到来时被唤醒。}}else if(child_process == 0){child_fun()}}return 0}僵尸进程的产生:
在fork()/execve()过程中,假设子进程结束时父进程仍存在,而父进程如果没有给子进程收尸,死掉的子进程就变成僵尸进程了。僵尸进程是非常特殊的一种,它已经放弃了几乎所有内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其他进程收集,除此之外,僵尸进程不再占有任何内存空间,它需要它的父进程来为它收尸。僵尸进程,无法正常结束,此时即使是root身份kill-9也不能杀死僵尸进程。补救办法是杀死僵尸进程的父进程(僵尸进程的父进程必然存在),僵尸进程成为"孤儿进程",过继给1号进程init,init始终会负责清理僵尸进程。
僵尸进程的危害:
Linux系统对运行的进程数量有限制,如果产生过多的僵尸进程占用了可用的进程号,将会导致新的进程无法生成。这就是僵尸进程对系统的最大危害。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)