假设这个程序在后台运行。
假设包含报头,例如signal.h...
void SignalHandler(int sig);
int fd;
int main(int argc, char *argv[]){
signal(SIGINT,SignalHandler);
signal(SIGHUP,SignalHandler);
signal(SIGTERM,SignalHandler);
setsid();
close(0);
close(1);
close(2);
fd = open("/myPIPE", O_RDWR);
if(fd<0){
perror("open() error");
exit(1);
}
while (1) {
err = read(fd, strbuf, 256);
if(err)
syslog(LOG_INFO,"%s",strbuf);
}
close(fd);
}
void SignalHandler(int sig){
if(fd!=-1)
close(fd);
exit(0);
}假设这段代码已经在运行。并且具有程序名testsignal。当我在终端./testsignal中再次运行它时,这个进程就会不断增加..当前运行的进程应该退出,并且新进程应该替换旧进程。所以应该只有进程在运行。我需要你的帮助。谢谢
发布于 2012-10-22 12:12:54
此代码是对您的代码的简化,因为它不使用syslog()。它也不会关闭标准输入、标准输出和标准错误,因此守护进程仍然可以将信息记录到标准输出中(特别是)。这使我更容易进行测试。
flprintf()函数用于确保所有到标准输出的输出都被刷新;它减少了程序中乏味的4行代码块的数量。该程序还记录了更多的活动,这也使它更容易看到正在发生的事情。(部分原因是我设法忽略了注释掉的close()系统调用。)我将所有不需要在这个源文件之外可见的东西都设为静态的;这意味着只有main()不是静态的。这段代码还确保读取的字符串是以null结尾的,这样紧跟短字符串的长字符串就不会产生短字符串和长字符串的混搭消息。
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <stdarg.h>
static void flprintf(const char *fmt, ...);
static void SignalHandler(int sig);
static int fd = -1;
int main(int argc, char **argv)
{
int nbytes;
char strbuf[257];
if (argc > 1)
{
int pid = atoi(argv[1]);
if (kill(pid, SIGINT) != 0)
flprintf("Failed to deliver SIGINT to PID %d\n", pid);
else
flprintf("SIGINT successfully delivered to PID %d\n", pid);
}
flprintf("Starting - %d\n", (int)getpid());
signal(SIGINT, SignalHandler);
signal(SIGHUP, SignalHandler);
signal(SIGTERM, SignalHandler);
setsid();
//close(0);
//close(1);
//close(2);
fd = open("./myPIPE", O_RDWR);
if (fd < 0)
{
perror("open() error");
exit(1);
}
flprintf("Starting read loop\n");
while ((nbytes = read(fd, strbuf, sizeof(strbuf)-1)) > 0)
{
strbuf[nbytes] = '\0';
flprintf("<<%s>>\n", strbuf);
}
flprintf("Read EOF - %d exiting\n", (int)getpid());
close(fd);
return(0);
}
void SignalHandler(int sig)
{
flprintf("Received signal %d - %d exiting\n", sig, (int)getpid());
if (fd != -1)
close(fd);
exit(0);
}
static void flprintf(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
fflush(stdout);
}我在Mac 10.7.5上进行了测试(GCC 4.7.1,在这种情况下这并不重要)。当它工作时,我发现唯一令我惊讶的行为是,当向FIFO写入消息的进程关闭时,程序没有获得EOF。但是,我认为open()调用上的O_RDWR可以解释这一点;仍然有一个进程(这个进程)打开了先进先出。使用O_RDONLY重新编译,在第一次向pipe...sanity规则写入内容后,进程退出。作为实现从不报告EOF的FIFO的一种方式,您所做的一切都是很好的。(它还解释了为什么进程没有在打开时阻塞,而是等待进程打开FIFO。)
示例输出:
$ ./sig >> sig.out &
[1] 47598
$ cat sig.out
Starting - 47598
Starting read loop
$ echo "Testing, 1, 2, 3" > myPIPE
$ cat sig.out
Starting - 47598
Starting read loop
<<Testing, 1, 2, 3
>>
$ echo "Another test - 1, 2, 3" > myPIPE
$ echo "Mini test - 1, 2" > myPIPE
$ cat sig.out
Starting - 47598
Starting read loop
<<Testing, 1, 2, 3
>>
<<Another test - 1, 2, 3
>>
<<Mini test - 1, 2
>>
$ ./sig 47598 >> sig.out &
[2] 47610
$ cat sig.out
Starting - 47598
Starting read loop
<<Testing, 1, 2, 3
>>
<<Another test - 1, 2, 3
>>
<<Mini test - 1, 2
>>
Received signal 2 - 47598 exiting
SIGINT successfully delivered to PID 47598
Starting - 47610
Starting read loop
[1]- Done ./sig >> sig.out
$ echo "Testing, 1, 2, 3" > myPIPE
$ cat sig.out
Starting - 47598
Starting read loop
<<Testing, 1, 2, 3
>>
<<Another test - 1, 2, 3
>>
<<Mini test - 1, 2
>>
Received signal 2 - 47598 exiting
SIGINT successfully delivered to PID 47598
Starting - 47610
Starting read loop
<<Testing, 1, 2, 3
>>
$ kill 47610
$ cat sig.out
Starting - 47598
Starting read loop
<<Testing, 1, 2, 3
>>
<<Another test - 1, 2, 3
>>
<<Mini test - 1, 2
>>
Received signal 2 - 47598 exiting
SIGINT successfully delivered to PID 47598
Starting - 47610
Starting read loop
<<Testing, 1, 2, 3
>>
Received signal 15 - 47610 exiting
[2]+ Done ./sig 47598 >> sig.out
$ https://stackoverflow.com/questions/13004221
复制相似问题