java was killed by signal 6怎么解决

java was killed by signal 6怎么解决,第1张

使用 dbx 调试程序 可能出于下列原因之一调试程序: 为了确定程序在何处以及为何导致崩溃。确定崩溃原因的方法包括: 在 dbx 中运行程序。dbx 会报告崩溃的发生位置。 检查核心转储文件并查看栈跟踪(请参见检查核心转储文件 and 查看调用栈)。

我也是初学者,这里抄一段《Linux设备驱动程序》书上的给你:

Linux的中断宏观分为两种:软中断和硬中断。声明一下,这里的软和硬的意思是指和软件相关以及和硬件相关,而不是软件实现的中断或硬件实现的中断。软中断就是“信号机制”。软中断不是软件中断。Linux通过信号来产生对进程的各种中断 *** 作,我们现在知道的信号共有31个,其具体内容这里略过。

一般来说,软中断是由内核机制的触发事件引起的(例如进程运行超时),但是不可忽视有大量的软中断也是由于和硬件有关的中断引起的,例如当打印机端口产生一个硬件中断时,会通知和硬件相关的硬中断,硬中断就会产生一个软中断并送到 *** 作系统内核里,这样内核就会根据这个软中断唤醒睡眠在打印机任务队列中的处理进程。

硬中断就是通常意义上的“中断处理程序”,它是直接处理由硬件发过来的中断信号的。当硬中断收到它应当处理的中断信号以后,就回去自己驱动的设备上去看看设备的状态寄存器以了解发生了什么事情,并进行相应的 *** 作。

对于软中断,我们不做讨论,那是进程调度里要考虑的事情。由于我们讨论的是设备驱动程序的中断问题,所以焦点集中在硬中断里。我们这里讨论的是硬中断,即和硬件相关的中断。

要中断,是因为外设需要通知 *** 作系统她那里发生了一些事情,但是中断的功能仅仅是一个设备报警灯,当灯亮的时候中断处理程序只知道有事情发生了,但发生了什么事情还要亲自到设备那里去看才行。也就是说,当中断处理程序得知设备发生了一个中断的时候,它并不知道设备发生了什么事情,只有当它访问了设备上的一些状态寄存器以后,才能知道具体发生了什么,要怎么去处理。

设备通过中断线向中断控制器发送高电平告诉 *** 作系统它产生了一个中断,而 *** 作系统会从中断控制器的状态位知道是哪条中断线上产生了中断。PC机上使用的中断控制器是8259,这种控制器每一个可以管理8条中断线,当两个8259级联的时候共可以控制15条中断线。这里的中断线是实实在在的电路,他们通过硬件接口连接到CPU外的设备控制器上。

并不是每个设备都可以向中断线上发中断信号的,只有对某一条确定的中断线勇有了控制权,才可以向这条中断线上发送信号。由于计算机的外部设备越来越多,所以15条中断线已经不够用了,中断线是非常宝贵的资源。要使用中断线,就得进行中断线的申请,就是IRQ(Interrupt Requirement),我们也常把申请一条中断线成为申请一个IRQ或者是申请一个中断号。

IRQ是非常宝贵的,所以我们建议只有当设备需要中断的时候才申请占用一个IRQ,或者是在申请IRQ时采用共享中断的方式,这样可以让更多的设备使用中断。无论对IRQ的使用方式是独占还是共享,申请IRQ的过程都是一样的,分为3步:

1.将所有的中断线探测一遍,看看哪些中断还没有被占用。从这些还没有被占用的中断中选一个作为该设备的IRQ。

2.通过中断申请函数申请选定的IRQ,这是要指定申请的方式是独占还是共享。

3.根据中断申请函数的返回值决定怎么做:如果成功了万事大吉,如果没成功则或者重新申请或者放弃申请并返回错误。

Linux中的中断处理程序很有特色,它的一个中断处理程序分为两个部分:上半部(top half)和下半部(bottom half)。之所以会有上半部和下半部之分,完全是考虑到中断处理的效率。

上半部的功能是“登记中断”。当一个中断发生时,他就把设备驱动程序中中断例程的下半部挂到该设备的下半部执行队列中去,然后就没事情了--等待新的中断的到来。这样一来,上半部执行的速度就会很快,他就可以接受更多她负责的设备产生的中断了。上半部之所以要快,是因为它是完全屏蔽中断的,如果她不执行完,其它的中断就不能被及时的处理,只能等到这个中断处理程序执行完毕以后。所以,要尽可能多得对设备产生的中断进行服务和处理,中断处理程序就一定要快。

但是,有些中断事件的处理是比较复杂的,所以中断处理程序必须多花一点时间才能够把事情做完。可怎么样化解在短时间内完成复杂处理的矛盾呢,这时候 Linux引入了下半部的概念。下半部和上半部最大的不同是下半部是可中断的,而上半部是不可中断的。下半部几乎做了中断处理程序所有的事情,因为上半部只是将下半部排到了他们所负责的设备的中断处理队列中去,然后就什么都不管了。下半部一般所负责的工作是察看设备以获得产生中断的事件信息,并根据这些信息(一般通过读设备上的寄存器得来)进行相应的处理。如果有些时间下半部不知道怎么去做,他就使用著名的鸵鸟算法来解决问题--说白了就是忽略这个事件。

由于下半部是可中断的,所以在它运行期间,如果其它的设备产生了中断,这个下半部可以暂时的中断掉,等到那个设备的上半部运行完了,再回头来运行它。但是有一点一定要注意,那就是如果一个设备中断处理程序正在运行,无论她是运行上半部还是运行下半部,只要中断处理程序还没有处理完毕,在这期间设备产生的新的中断都将被忽略掉。因为中断处理程序是不可重入的,同一个中断处理程序是不能并行的。

在Linux Kernel 20以前,中断分为快中断和慢中断(伪中断我们这里不谈),其中快中断的下半部也是不可中断的,这样可以保证它执行的快一点。但是由于现在硬件水平不断上升,快中断和慢中断的运行速度已经没有什么差别了,所以为了提高中断例程事务处理的效率,从Linux kernel 20以后,中断处理程序全部都是慢中断的形式了--他们的下半部是可以被中断的。

但是,在下半部中,你也可以进行中断屏蔽--如果某一段代码不能被中断的话。你可以使用cti、sti或者是save_flag、restore_flag来实现你的想法。

在处理中断的时候,中断控制器会屏蔽掉原先发送中断的那个设备,直到她发送的上一个中断被处理完了为止。因此如果发送中断的那个设备载中断处理期间又发送了一个中断,那么这个中断就被永远的丢失了。

之所以发生这种事情,是因为中断控制器并不能缓冲中断信息,所以当前一个中断没有处理完以前又有新的中断到达,他肯定会丢掉新的中断的。但是这种缺陷可以通过设置主处理器(CPU)上的“置中断标志位”(sti)来解决,因为主处理器具有缓冲中断的功能。如果使用了“置中断标志位”,那么在处理完中断以后使用sti函数就可以使先前被屏蔽的中断得到服务。

有时候需要屏蔽中断,可是为什么要将这个中断屏蔽掉呢?这并不是因为技术上实现不了同一中断例程的并行,而是出于管理上的考虑。之所以在中断处理的过程中要屏蔽同一IRQ来的新中断,是因为中断处理程序是不可重入的,所以不能并行执行同一个中断处理程序。在这里我们举一个例子,从这里子例中可以看出如果一个中断处理程序是可以并行的话,那么很有可能会发生驱动程序锁死的情况。当驱动程序锁死的时候,你的 *** 作系统并不一定会崩溃,但是锁死的驱动程序所支持的那个设备是不能再使用了--设备驱动程序死了,设备也就死了。

A是一段代码,B是 *** 作设备寄存器R1的代码,C是 *** 作设备寄存器R2的代码。其中激发PS1的事件会使A1产生一个中断,然后B1去读R1中已有的数据,然后代码C1向R2中写数据。而激发PS2的事件会使A2产生一个中断,然后B2删除R1中的数据,然后C2读去R2中的数据。

如果PS1先产生,且当他执行到A1和B1之间的时候,如果PS2产生了,这是A2会产生一个中断,将PS2中断掉(挂到任务队列的尾部),然后删除了 R1的内容。当PS2运行到C2时,由于C1还没有向R2中写数据,所以C2将会在这里被挂起,PS2就睡眠在代码C2上,直到有数据可读的时候被信号唤醒。这是由于PS1中的B2原先要读的R1中的数据被PS2中的B2删除了,所以PS1页会睡眠在B1上,直到有数据可读的时候被信号唤醒。这样一来,唤醒PS1和PS2的事件就永远不会发生了,因此PS1和PS2之间就锁死了。

由于设备驱动程序要和设备的寄存器打交道,所以很难写出可以重入的代码来,因为设备寄存器就是全局变量。因此,最简洁的办法就是禁止同一设备的中断处理程序并行,即设备的中断处理程序是不可重入的。

有一点一定要清楚:在20版本以后的Linux kernel中,所有的上半部都是不可中断的(上半部的 *** 作是原子性的);不同设备的下半部可以互相中断,但一个特定的下半部不能被它自己所中断(即同一个下半部不能并)。

由于中断处理程序要求不可重入,所以程序员也不必为编写可重入的代码而头痛了。编写可重入的设备驱动程序是可以的,编写可重入的中断处理程序是非常难得,几乎不可能。

我们都知道,一旦竞争条件出现了,就有可能会发生死锁的情况,严重时可能会将整个系统锁死。所以一定要避免竞争条件的出现。只要注意一点:绝大多数由于中断产生的竞争条件,都是在带有中断的

内核进程被睡眠造成的。所以在实现中断的时候,一定要相信谨慎的让进程睡眠,必要的时候可以使用cli、sti或者save_flag、restore_flag。

这是一个不知所云的程序不知道写这个程序的人目的是什么, 是为了教会你什么东西

你看到这3个 is killed的printf结果,属于3个不同的进程的输出, 彼此不存在依存关系。所以,并不是像你说的程序“还能跑到最里面”的if去执行, 而是 2个fork 创建了2个子进程, 主进程在最里面的if sleep,而2个子进程先后打印退出。

signal()和kill()一般也不是必须搭配使用的, signal是重新定义进程对于信号的处理方式。 而kill是向另外一个进程发送信号。

killed的意思为:被杀死的,断开的,杀死,击毙,破坏,减弱,抵消;使痛苦,使受折磨。

基本解释:v 杀死; 弄死; 导致死亡; 毁灭; 破坏; 扼杀; 使停止; 使痛苦; 使疼痛; 使受折磨; adj 被杀死的;被屠宰的;冶镇静的;化饱和了的;kill的过去分词和过去式。

短语搭配:Monsters Killed 敌方死亡人数 ; 击杀怪物数量 ; 杀了几只怪 ; 敌方死亡数

Rabbits killed 杀掉的兔子的数量 ; 兔子的宰杀数量;being killed 丧生 ; 被杀害

People killed 杀人的数量 ; 使人丧命;Armadillos killed 犰狳的宰杀数量

Wolves killed 狼的宰杀数量;Al Killed 铝镇静;Chickens killed 鸡的宰杀数量

killed造句:Most of his lieutenants have been killed or arrested 他的副手大部分都被杀死或逮捕了。

Pakistani reporters going after stories are killed there every year 每年都有采录新闻的记者在那里遇害。

They also got video messages with doctored images purporting to show the bodies of muslims killed in assam 他们同样收到伪造的的视频信息,意图展示在阿萨姆邦被杀死的穆斯林的尸体。

This organization killed hundreds of american marines in 1983 这个组织在1983年杀死了数百名美国海军士兵。

测试了一下,三个进程都会收到SIGINT信号。

原程序中,child1, child2都收到SIGINT信号,调用stop(), 之后被唤醒,打印"child process is killed by parent!",事实上kill这两个child的不是parent,是它们自己的SIGINT。

放到①处,child1收到SIGINT信号,默认的行为是把自己杀了,当然也来不及打印任何东西了。child2收到SIGINT信号,打断waiting(),打印"child process 2 ",然后退出。杀死它的也不是SIGUSR2信号。

放到②处,child1, child2收到SIGINT信号,默认的行为是立即把自己杀了,也来不及打印任何东西了。

测试方法:

// 打印谁执行、被什么信号打断

static void stop(int signal) {

printf("stop %d by signal %d\n", getpid(), signal);

wait_mark=0;

}

// 在parent进程中,打印各进程id

printf("parent %d, child1 %d, child2 %d\n",getpid(),p1,p2);

如果让parent成为杀死child的凶手,可以在child1,child2中加入:

signal(SIGINT, keep_me_alive);

// 不理睬SIGINT信号

static void keep_me_alive(int signal) {

}

这时打印结果就一样了

以上就是关于java was killed by signal 6怎么解决全部的内容,包括:java was killed by signal 6怎么解决、LINUX软中断通信、关于linux C中的signal()和kill()的问题等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zz/9603339.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-30
下一篇 2023-04-30

发表评论

登录后才能评论

评论列表(0条)

保存