我确定我的问题可能已经回答过了,但是在搜索了一段时间后我没有发现任何与我的情况有关的问题。
背景
我在C中编写了一套数据采集工具,运行在运行Debian Wheezy的嵌入式系统上。有一个名为Dispatch的主模块,其工作是启动其余模块并在它们之间传递消息。我在/etc/init.d
中放了一个简单的bash脚本,当系统启动时执行Dispatch,因为这个系统无人值守运行。这个系统在没有任何本地用户交互的情况下运行,因此Dispatch应该真正被编写为一个守护进程,但事实并非如此。启动脚本只执行/opt/bcdispatch &
。
其他一个模块中有一个错误导致它每隔几天就崩溃一次。我正在尝试追捕那个错误,但与此同时我正在尝试编写一个监视程序来检测崩溃,杀死我的所有进程,然后重新启动Dispatch。由于原因我不会仅仅重新启动崩溃的过程,因此需要重新启动整套工具。
我正在尝试做什么:
我编写了一个简单的看门狗程序,定期执行popen("ps aux | grep bc")
(我的所有进程名称都以“bc”开头,这样可以很容易地用grep找到它们),发现其中一个模块因查找而崩溃了从popen()
读取的任何行中都有“僵尸”状态的任何内容,通过调用system("kill <PID>")
来杀死我的所有进程,然后在/etc/init.d
中执行启动脚本并退出。我修改了启动脚本,以便在启动Dispatch后启动监视程序。启动脚本现在看起来像:
/opt/bcdispatch &
/opt/mywatchdog &
一切都以root身份运行。系统上没有其他用户帐户。
问题
如果我从命令行运行它,看门狗进程可以正常工作。它会终止它应该执行的所有进程,启动启动脚本,然后退出。但是,当启动脚本在启动时启动监视程序时,它不会执行任何操作。它正在运行,它监视的进程之一已经崩溃,但它并没有杀掉其余的进程。它只是坐在那里像一个巨大的粪便。我可以从命令行启动它的另一个实例,并且一个工作正常。
问题
所以我的问题(终于!)是:为什么我的程序在通过启动脚本启动时不能杀死其他进程?我怀疑它与监视程序进程不再有与之关联的终端这一事实有关?我尝试用system("kill <PID>")
将调用替换为kill(PID)
,但这并未改变任何内容。
修改
我刚刚想到,不是kill()部分不起作用(好吧,也可能会被打破),对popen(“ps aux | grep bc”)的调用一定不能正常工作因为监视器应该在找到僵尸进程后退出,但事实并非如此。它的PID仍然与系统启动时的PID相同。我想这意味着这个问题的标题不是很好。
答案 0 :(得分:1)
发现问题。看门狗对ps
的调用输出被截断为80列,大概是因为它不再附加到终端而且是默认的终端宽度。该截断导致程序解析popen("ps -w aux | grep bc")
命令结果的方式出现问题,因此它从未发现崩溃的进程。将命令更改为public void loadData(){
pd=new ProgressDialog(this);
pd.setMessage("loading");
pd.show();
mApi= new RetrofitHelper<AuthApi>().getApi(AuthApi.class);
mCall=mApi.studentlist(pageNo);
mCall.enqueue(new Callback<ResultObject<ArrayList<Person>>>() {
@Override
public void onResponse(Call<ResultObject<ArrayList<Person>>> call,
Response<ResultObject<ArrayList<Person>>> response) {
// check responce null or not
if(response!=null && response.size()>0){
for(int i=0;i<response.body().getData().size();i++){
mData.add(response.body().getData().get(i));
}
count=response.body().getCount();
mAdapter=new PersonAdapter(Members.this,R.layout.item_person,mData);
list.setAdapter(mAdapter);
pd.hide();
}
}
@Override
public void onFailure(Call<ResultObject<ArrayList<Person>>> call,
Throwable t) {
Toast.makeText(Members.this,"failed",Toast.LENGTH_SHORT).show();
pd.hide();
}
});
}
只需要修复它。