java编程 applet的执行从三个方法调用()()和()开始

1021人阅读
嵌入式操作系统(18)
#include &stdio.h&
#include &stdlib.h&
#include&signal.h&
#include&sys/types.h&
void func()
puts(&hello&);
int main(void) {
signal(SIGALRM,func);//当接受到ALARM信号时就做func函数里面做的事情父
alarm(4);//设置4秒的脑中
pause();//产生中断,去执行func函数
//如果把前面的signal(SIGINT,SIGDEF);去掉,则该程序不会有任何输出,因为alarm信号的默认处理方式 就是退出
puts(&I am going on&);
// signal(SIGINT,SIG_IGN);//Y一旦遇到SIGINT这个信号,就将其忽略掉,按 ctrl+c是不会干扰的,要想退出进程可以ctrl+z
// signal(SIGINT,func);//一旦遇到终端,就执行func这个函数
// signal(SIGINT,SIG_DFL);//这个是不产生任何的影响的
return EXIT_SUCCESS;
1.通过信号量通信:
============================================================================
: connectBySignal.c
: Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
* 1.子进程继承父进程之前运行的一切状态,包括对于信号处理方式的修改。
* 2.ctrl+c异步事件的产生,导致内核发出的sigint信号会发给前台进程组*/
#include &stdio.h&
#include &stdlib.h&
#include&signal.h&
#include&unistd.h&
#include&sys/wait.h&
//系统调用signal()让父进程捕捉键盘上的中断信号,捕捉后,父进程用系统调用用kill()向两个子进程发出信号,然后子进程各自输出
void waiting()
while(wait_mark!=0);
void stop()
wait_mark=0;
int main(void)
int p1,p2;
signal(SIGINT,stop);//接受到ctrl+c信号,stop111
while((p1=fork())==-1);
{ //signal(SIGINT,stop);//222
while((p2=fork())==-1);
{ //signal(SIGINT,stop);//3333333
wait_mark=1;
waiting();
kill(p1,10);
kill(p2,12);
wait(NULL);
wait(NULL);
puts(&father exits&);
else if(p2==0)
wait_mark=1;
signal(12,stop);
waiting();
lockf(1,1,0);//第一个参数的标志1是标准输出
printf(&child2 process is killed by father\n&);
lockf(1,0,0);
wait_mark=1;
signal(10,stop);
waiting();
lockf(1,1,0);
puts(&child1 process is killed buy father&);
lockf(1,0,0);
return EXIT_SUCCESS;
/*对于三种不同的安置情况对应的结果及其分析
* 1.首先是通过signal(SIGINT,stop);来设置当遇到ctrl+c信号时就用stop来处理
* 之后创建了一个子进程,在父进程里面再创建一个子进程,在父进程中,分别给两个子进程通过kill发送usr1,和usr2信息,对应数字为10,12
* 然后在子进程1里面,等待标志为1,并且设置当受到usr1信号是用终止来处理,之后等待触发ctrl+c事件,触发后从waiting事件走出来,打印自己的信息,被父进程杀死
* 进程2同理
* child1 process is killed buy father
child2 process is killed by father
father exits
* 2.这个是在创建子进程之后的设置signal(SIGINT,stop);,所以子进程1就不会继承到这个信号,一直就处于等待接受usr1信号,但是如果接收到ctrl+c,就自动中止
* 而子进程2还是可以接受的
* child2 process is killed by father
father exits
*3.两个子进程都没能接受到usr1或usr2,遇到ctrl+c信号后直接退出
*father exits/
2.通过信号量通信
&============================================================================
&Name&&&&&&& : connectBySignal2.c
&Author&&&&& :
&Version&&&& :
&Copyright&& : Your copyright notice
&Description : Hello World in C, Ansi-style
&============================================================================
//对上一个程序进行修改,增加语句signal(SIGINT,SIG_INT)和语句signal(SIGQUIT,SIG_IGN)
#include &stdio.h&
#include &stdlib.h&
#include&signal.h&
#include&unistd.h&
#include&sys/wait.h&
int pid1,pid2;
//一个进程中多次调用signal函数,以最后一次的设置为准
void Initdelete()
&& &kill(pid1,10);//给两个子进程分别发送usr1和usr2信号
&& &kill(pid2,12);
void Init1()
&& &puts(&child1 process is killed by father&);
&& &exit(1);
void Init2()
&& &puts(&child2 process is killed by father&);
&& &exit(0);
int main(void) {
&& &signal(SIGINT,SIG_IGN);//当遇到中断时,响应忽略,如果这一步舍去了,就不能保证子进程在遇到ctrl+c信号时会处理,而时会按默认方式直接终止
&& &signal(SIGQUIT,SIG_IGN);
&& &pid1=fork();
&& &if(pid1&0)
&& &&& &pid2=fork();//创建第一个子进程
&& &&& &if(pid2&0)
&& &&& &signal(SIGINT,Initdelete);//当出现ctrl+c信号的时候,用Initdelete来处理
&& &&& &waitpid(-1,NULL,0);//等待任何子进程中断或者结束
&& &&& &waitpid(-1,NULL,0);//等待任何子进程中断或者结束
&& &&& &puts(&father exit&);
&& &&& &exit(0);
&& &&& &else
&& &&& &&& &signal(12,Init2);
&& &&& &&& &pause();
&& &&& &&& &exit(0);
&& &else if(pid1==0)
&& &&& &signal(10,Init1);//获得usr1信号用,用Init来处理这个函数
&& &&& &pause();//应该是在没有信号时挂起,当有信号时唤醒执行init1
&& &&& &exit(0);
&& &return EXIT_SUCCESS;
3.司机售票员问题:
创建子进程代表售票员,父进程代表司机,同步过程如下:
售货员捕捉SIGINT(代表开车),发SIGUSR1给司机,司机打印:let us go go go
售票员捕捉SIFQUIT(代表开车),发SIGUSR2给司机,司机:top the bus
司机捕捉SIGTSTP(代表车到总站),发SIGUSR1给售票员,售票员打印:please get off the bus
============================================================================
: busConnect.c
: Your copyright notice
Description : Hello World in C, Ansi-style
============================================================================
#include &stdio.h&
#include &stdlib.h&
#include&sys/wait.h&
#include&signal.h&
#include&unistd.h&
int pid1,pid2;
void Init1()
puts(&let us go go go&);
void Init2()
puts(&stop the bus&);
void Init3()
puts(&please get off the bus&);
void Init4()
kill(pid1,10);
void Init5()
int k=getppid();
kill(k,10);
void Init6()
int j=getppid();
kill(j,12);
int main(void)
& &signal(SIGINT,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
signal(SIGTSTP,SIG_IGN);
pid1=fork();
if(pid1&0)//父进程
signal(10,Init1);
signal(12,Init2);
signal(SIGTSTP,Init4);
else if(pid1==0)
signal(SIGINT,Init5);
signal(SIGQUIT,Init6);
signal(10,Init3);
puts(&wrong&);
return EXIT_SUCCESS;
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:74329次
积分:1520
积分:1520
排名:千里之外
原创:71篇
转载:24篇
评论:23条
(2)(1)(1)(2)(1)(1)(2)(1)(2)(2)(1)(3)(1)(1)(2)(1)(9)(17)(1)(17)(20)(8)2863人阅读
JVM 源码分析(50)
Linux 内核源码分析(31)
在java 中调用Signal的方法handle可以去注册一个信号的处理函数,方法的如下:
public static synchronized SignalHandler handle(Signal sig,
SignalHandler handler) {
比如常用的addShutdownHook钩子函数里,就是在&Terminator.setup();的时候将Shutdown.exit 的函数注册到了信号SHUTDOWN1_SIGNAL(SIGHUP),SHUTDOWN2_SIGNAL(SIGINT),SHUTDOWN3_SIGNAL(SIGTERM)中,当线程接受到信号时,通过调用函数Shutdown.exit的调用hook中的钩子函数。
在笔者的文章()也提到jdk如何处理信号的,那么调用handle里是不是直接就把这个方法注册进了信号处理呢?
请注意,handle是一个java的方法,而注册信号函数是c的代码,显然不能简单的将java的方法直接提供给c调用,其次信号处理函数是在内核态中处理,安全性和执行时间的长短将影响到内核的信号调度。
先看java源码,如下面所示
public static synchronized SignalHandler handle(Signal sig,
SignalHandler handler)
throws IllegalArgumentException {
long newH = (handler instanceof NativeSignalHandler) ?
((NativeSignalHandler)handler).getHandler() : 2;
long oldH = handle0(sig.number, newH);
if (oldH == -1) {
throw new IllegalArgumentException
(&Signal already used by VM: & + sig);
signals.put(new Integer(sig.number), sig);
synchronized (handlers) {
SignalHandler oldHandler = (SignalHandler)handlers.get(sig);
handlers.remove(sig);
if (newH == 2) {
handlers.put(sig, handler);
if (oldH == 0) {
return SignalHandler.SIG_DFL;
} else if (oldH == 1) {
return SignalHandler.SIG_IGN;
} else if (oldH == 2) {
return oldH
return new NativeSignalHandler(oldH);
}在native code hand0里并没有将handle的方法传进去,只是传了一个整型值。
在c++代码中hand0里调用了函数&JVM_RegisterSignal,具体来看一下这个函数的实现
JVM_ENTRY_NO_ENV(void*, JVM_RegisterSignal(jint sig, void* handler))
// Copied from classic vm
// signals_md.c
1.4 98/08/23
void* newHandler = handler == (void *)2
? os::user_handler()
switch (sig) {
/* The following are already used by the VM. */
case INTERRUPT_SIGNAL:
case SIGFPE:
case SIGILL:
case SIGSEGV:
/* The following signal is used by the VM to dump thread stacks unless
ReduceSignalUsage is set, in which case the user is allowed to set
his own _native_ han thus, in either case,
we do not allow JVM_RegisterSignal to change the handler. */
case BREAK_SIGNAL:
return (void *)-1;
/* The following signals are used for Shutdown Hooks support. However, if
ReduceSignalUsage (-Xrs) is set, Shutdown Hooks must be invoked via
System.exit(), Java is not allowed to use these signals, and the the
user is allowed to set his own _native_ handler for these signals and
invoke System.exit() as needed. Terminator.setup() is avoiding
registration of these signals when -Xrs is present.
- If the HUP signal is ignored (from the nohup) command, then Java
is not allowed to use this signal.
case SHUTDOWN1_SIGNAL:
case SHUTDOWN2_SIGNAL:
case SHUTDOWN3_SIGNAL:
if (ReduceSignalUsage) return (void*)-1;
if (os::Linux::is_sig_ignored(sig)) return (void*)1;
void* oldHandler = os::signal(sig, newHandler);
if (oldHandler == os::user_handler()) {
return (void *)2;
return oldH
void* newHandler = handler == (void *)2
? os::user_handler()
:因为传进的值是2,那么真正在c++里的信号处理函数实际上os::user_handler(),同时jvm也保护了几个信号,不允许外部改变信号的处理函数。
一切豁然开朗,笔者的博客()已经提到过这个函数,通过os:signal_notify 去通知signal
dispatcher 线程的os::signal_wait,也就是接受到信号的线程通过信号函数notify到处理信号的线程(signal dispatcher ),最后由该线程做后续的事情。
具体来看signal dispatcher 的thread entry
static void signal_thread_entry(JavaThread* thread, TRAPS) {
default: {
// Dispatch the signal to java
HandleMark hm(THREAD);
klassOop k = SystemDictionary::resolve_or_null(vmSymbolHandles::sun_misc_Signal(), THREAD);
KlassHandle klass (THREAD, k);
if (klass.not_null()) {
JavaValue result(T_VOID);
args.push_int(sig);
JavaCalls::call_static(
vmSymbolHandles::dispatch_name(),
vmSymbolHandles::int_void_signature(),
也就是在jvm的c++源码中,反调用了java的方法,也就是signal.java中的dispatch(int number),方法dispatch中才是真正的调用了在文章开头提到的注册到Signal的方法handle。
dispatch方法中仍然起了一个新的线程去处理handle,这样就不会block&signal
dispatcher 线程。
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:323118次
积分:4040
积分:4040
排名:第6995名
原创:92篇
评论:48条
(3)(6)(5)(2)(1)(3)(6)(1)(7)(3)(1)(1)(1)(3)(1)(6)(5)(1)(2)(1)(1)(1)(1)(1)(1)(1)(2)(3)(1)(4)(2)(2)(1)(2)(2)(4)(1)(2)(1)(1)(2)本帖子已过去太久远了,不再提供回复功能。1517人阅读
linux(33)
C/C++(70)
sigaction使用
可以参考的几个man
man sigaction&&
man 7 signal
Signal&&&& Value&&&& Action&& Comment
----------------------------------------------------------------------
SIGHUP&&&&&&& 1&&&&&& Term&&& Hangup detected on controlling terminal
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& or death of controlling process
SIGINT&&&&&&& 2&&&&&& Term&&& Interrupt from keyboard
SIGQUIT&&&&&& 3&&&&&& Core&&& Quit from keyboard
SIGILL&&&&&&& 4&&&&&& Core&&& Illegal Instruction
SIGABRT&&&&&& 6&&&&&& Core&&& Abort signal from abort(3)
SIGFPE&&&&&&& 8&&&&&& Core&&& Floating point exception
SIGKILL&&&&&& 9&&&&&& Term&&& Kill signal
SIGSEGV&&&&& 11&&&&&& Core&&& Invalid memory reference
SIGPIPE&&&&& 13&&&&&& Term&&& Broken pipe: write to pipe with no
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& readers
SIGALRM&&&&& 14&&&&&& Term&&& Timer signal from alarm(2)
SIGTERM&&&&& 15&&&&&& Term&&& Termination signal
SIGUSR1&& 30,10,16&&& Term&&& User-defined signal 1
SIGUSR2&& 31,12,17&&& Term&&& User-defined signal 2
SIGCHLD&& 20,17,18&&& Ign&&&& Child stopped or terminated
SIGCONT&& 19,18,25&&& Cont&&& Continue if stopped
SIGSTOP&& 17,19,23&&& Stop&&& Stop process
SIGTSTP&& 18,20,24&&& Stop&&& Stop typed at tty
...............
这里注意下sigkill和sigstop不能忽略 捕捉。
kill -s signal pid
先看看struct sigaction的定义
struct sigaction
&&& void (*sa_handler)(int); /* addr of signal handler or&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& SIG_IGN, SIG_DFL */
&&& sigset_t sa_&&&&&&& /* additional signals to block */
&&& int sa_&&&&&&&&&&& /* signal options */
&&& /* alternate handler */
&&& void (*sa_sigaction)(int, siginfo_t *, void *);
如果不设置sa_flags的话,初始化为void (*sa_handler)(int);//这个就和signal差不多了哦
void handler(int signo);
如果设置了SA_SIGINFO则,初始化为void (*sa_sigaction)(int, siginfo_t *, void *);
//多了个siginfo,这个结构体的定义参见APUE,还有哥context,用于标识信号传递时进程的上下文
void handler(int signo, siginfo_t* info, void* context);
注意两者不可以同时使用...
1.简简单单的只是完成跟signal一样的功能,不用传任何值给信号处理函数
#include &sys/types.h&
#include &unistd.h&
#include &stdio.h&
#include &signal.h&
void sig_op(int signo)
& printf(&the signo is %d\n&,signo);
int main(int argc,char** argv)
&pid=getpid();
&sigemptyset(&act.sa_mask);
&act.sa_handler=sig_&
&act.sa_flags=0;
&printf(&the pid is %d&,pid);
&if(sigaction(SIGPIPE,&act,NULL)==-1)
& printf(&install error~!\n&);
&& sleep(1);
&& printf(&wait for signal\n&);
& return 0;
[kenthy@kenthy c_c]$ ./sig
the pid is 3882
wait for signal
wait for signal
wait for signal
wait for signal
the signo is 13//这个时候另一个terminal&& kill -s SIGPIPE 3882
wait for signal
wait for signal
wait for signal
2. sigaction本色使用
#include &sys/types.h&
#include &unistd.h&
#include &stdio.h&
#include &signal.h&
& struct siginfo
&& int si_
&& int si_
&& int si_
&& pid_t si_
&& uid_t si_
&& void* si_
&& int si_
&& long s_band
void sig_op(int signo, siginfo_t* info, void* context)
& printf(&the signo is %d\n&,signo);
& printf(&sig pid is %d\n&, (int)(info-&si_pid));
& printf(&sig uid is %d\n&, (int)(info-&si_uid));
int main(int argc,char** argv)
&pid=getpid();
&sigemptyset(&act.sa_mask);
&act.sa_handler=sig_&
&act.sa_flags=SA_SIGINFO;
&printf(&the pid is %d&,pid);
&if(sigaction(SIGPIPE,&act,&oact)==-1)
&&//这里还可以保存原来的signal处理方式,以便有的时候需要恢复oact。
&&//sigaction(sig,&oact,NULL)
& printf(&%s&,&install error~!\n&);
&& sleep(1);
&& printf(&%s&,&wait for signal\n&);
& return 0;
[kenthy@kenthy c_c]$ ./sig
the pid is 3904
wait for signal
wait for signal
wait for signal
wait for signal
wait for signal
wait for signal
the signo is 13 //这个时候另一个terminal&& kill -s SIGPIPE 3904
sig pid is 3135
sig uid is 500
wait for signal
wait for signal
uid是500可以理解....
sig pid是3135不解,也不想解
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:99436次
积分:1330
积分:1330
排名:千里之外
原创:10篇
转载:168篇
(1)(1)(1)(2)(4)(3)(1)(2)(1)(2)(7)(1)(7)(4)(2)(1)(3)(4)(1)(1)(5)(1)(2)(2)(13)(2)(21)(11)(74)

我要回帖

更多关于 java编程 的文章

 

随机推荐