linux进程和信号

原创:https://blog.csdn.net/ndzjx/article/details/88943008

进程:“一个其中运行着一个或多个线程的地址空间和这些线程所需要的系统资源”

进程之间会共享程序代码和系统函数库。

PID为1,为特殊进程init保留,负责管理其他进程。

系统根据进程的nice值来决定优先级。值越大优先级越低。(ps -l ) NI列

启动新进程:

1:system函数(阻塞),可以后台运行,如system(“ps -ax &”);

2:exec函数系列,把当前进程替换为一个新进程。原进程已打开的文件描述符在新进程中仍将保持打开,

除非他们的“执行时关闭标志”被置位。任何在原进程中已打开的目录流都将在新进程中被关闭。

3:fork

等待一个进程:wait

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

int main()
{
    pid_t pid;
    char *message;
    int n;
    int exit_code;

    printf("fork program starting\n");
    pid = fork();
    switch(pid) 
    {
    case -1:
        exit(1);
    case 0:
        message = "This is the child";
        n = 5;
        exit_code = 37;
        break;
    default:
        message = "This is the parent";
        n = 3;
        exit_code = 0;
        break;
    }

    for(; n > 0; n--) {
        puts(message);
        sleep(1);
    }

/*  This section of the program waits for the child process to finish.  */

    if(pid) {
        int stat_val;
        pid_t child_pid;

        child_pid = wait(&stat_val);

        printf("Child has finished: PID = %d\n", child_pid);
        if(WIFEXITED(stat_val))
            printf("Child exited with code %d\n", WEXITSTATUS(stat_val));
        else
            printf("Child terminated abnormally\n");
    }
    return exit_code;
}

僵尸进程:子进程终止时,它与父进程的关联还会保持,直到父进程也终止或者父进程调用wait才告结束。因此,进程表中代表子进程的表项不会立刻释放。退出码还需要保存起来以备父进程wait调用使用。

waitpid函数有一个选项:WNOHANG,作用是防止waitpid调用将调用者的执行挂起。

waitpid(child_pid, (int *)0, WNOHANG);

kill 可以发送信号,如:

kill -HUP 512

void (*signal(int sig, void (*func)(int)))(int);

返回一个函数,即先前用来处理这个信号的函数。

可以用两个特殊值来代替信号处理函数:

SIG_IGN 忽略信号

SIG_DFL 恢复默认行为

int kill(pid_t pid, int sig) 发送信号

int pause(void); 等待信号

程序中信号使用的特殊问题:“如果信号出现在系统调用的执行过程中会发生什么情况?”答案是“视情况而定”

健壮的信号接口:

替代signal →>>>

int sigaction(int sig, const struct sigaction *act, struct sigaction *oace)

该结构至少包含如下成员:

void (*) (int) sa_handler;

sigset_t sa_mask;

int sa_flags;

其中,sa_mask,指定一个信号集,在调用sa_handler指向的信号处理函数之前,该信号集被加入到进程的信号屏蔽字中,这是一组被阻塞且不会传递给该进程的信号。

sa_flags 可以设置重置效果等。SA_RESTART

代替pause 等待信号---→> >>>>> int sigsuspend(const sigset_t *sigmask)

如果信号被阻塞,就不会传递给进程,会停留在待处理状态,函数sigpending来查看它阻塞的信号中有哪些正停留在待处理状态。

#include <stdio.h>
#include <unistd.h>
#include <signal.h>

void ouch(int sig)
{
    printf("OUCH! - I got signal %d\n", sig);
}

int main()
{
    struct sigaction act;

    act.sa_handler = ouch;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;

    sigaction(SIGINT, &act, 0);

  while(1) {
    printf("Hello World!\n");
    sleep(1);
  }
}

猜你喜欢

转载自blog.csdn.net/ndzjx/article/details/88943008