首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >获取特定PID的状态。

获取特定PID的状态。
EN

Stack Overflow用户
提问于 2014-01-08 15:05:48
回答 5查看 27.2K关注 0票数 10

问题很简单,但我还没有找到答案。给定一个特定的PID,我能否确定该进程是否处于活动状态?我在做一个C程序,这让我发疯了。我在某个地方读到了kill(pid,0)可以做到这一点,但是不管进程是否正在运行(或者看起来是这样),它都会返回0。

有什么暗示吗?

附加信息:我感兴趣的过程是一个由fork()发起的子程序。子进程应该在到达语句exit(0).时终止--至少这正是我所期望的.显然不是。

更多信息:使用fork()创建的子进程执行一个系统命令,该命令可以根据最终用户的不同而有所不同。整个过程是一个批处理过程的一部分,所以没有机会跳进去修复一些东西。这个子进程可能必须执行的任务之一是建立到远程服务器的连接,以便在那里存储一些文档。这可能是另一台Linux机器,也可能是Win Server (或者其他什么东西)。因此,我不想等待子进程。我希望父进程等待一段特定的时间(例如10秒),然后如果其子进程到那时还没有完成,就关闭它。同样,如果子进程在3毫秒内完成任务,我不希望父进程等待10秒。

看来我不是第一个遇到这个问题的人。

EN

Stack Overflow用户

发布于 2014-01-10 19:46:44

阿基姆,我是以最无耻的方式这么做的,但这就是我的想法。如果您想使用毫秒,可以使用和itimer,或者更好的是使用timer_create而不是alarm。如果您想要扩展它以处理多个子项目(或者在父级中做一些有用的事情),您也可以这样做。

代码语言:javascript
复制
#define _POSIX_C_SOURCE 1

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/types.h>

pid_t cpid;    
volatile sig_atomic_t done = 0;

void alarmHandler(int signum)
{
    if (kill(cpid, SIGTERM) != -1)
        printf("kill signal sent to child from parent\n");
    else
        if (errno == ESRCH)
            printf("kill could not find child, must already be dead\n");
        else
        {
            perror("kill");
            exit(EXIT_FAILURE);
        }
}

void childHandler(int signum)
{
    pid_t childpid;
    int status;

    while ((childpid = waitpid( -1, &status, WNOHANG)) > 0)
    {    
        if (WIFEXITED(status))
            printf("Child %d exited naturally\n", childpid);

        if (WIFSIGNALED(status))
            printf("Child %d exited because of signal\n", childpid);
    }

    if (childpid == -1 && errno != ECHILD)
    {
        perror("waitpid");
        exit(EXIT_FAILURE);
    }

    done = 1;
}

int main (int argc, char *argv[])
{
    int sleepSecs;
    int timeoutSecs;

    if (argc < 3)
    {
        printf("\nusage: %s sleep-seconds timeout-seconds\n\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    sscanf(argv[1], "%d", &sleepSecs);
    sscanf(argv[2], "%d", &timeoutSecs);

    signal(SIGCHLD, childHandler);
    signal(SIGALRM, alarmHandler);

    if ((cpid = fork()) == -1)
    {
        printf("%d : failed to start child process.\n", errno);
        perror("fork");
        exit( -1);
    }

    if (cpid == 0) //child
    {
        execl("./sleeping_child", "./sleeping_child", argv[1], (char *) NULL);

        perror("execl");
        exit(EXIT_FAILURE);
    }
    else //parent
    {
        alarm(timeoutSecs);

        while (! done)
        {
            sleep(1); // or do something useful instead
        }

        exit(0);
    }
}

儿童程序不需要做任何特别的事情就会死去。

代码语言:javascript
复制
/* sleeping_child */
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main (int argc, char * argv[]) 
{
    printf("child will sleep for %s seconds\n", argv[1]);

    sleep(atoi(argv[1]));

    exit(0);
}

一些示例运行如下所示

代码语言:javascript
复制
$ simpleReap 3 1
child will sleep for 3 seconds
kill signal sent to child from parent
Child 5095 exited because of signal

$ simpleReap 1 3
child will sleep for 1 seconds
Child 5097 exited naturally
票数 0
EN
查看全部 5 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20999255

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档