c进程

First Post:

Last Update:

Word Count:
1.2k

Read Time:
5 min

获取进程信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <unistd.h>
#include <stdio.h>
#include <pwd.h>


int main(void) {
/*
#include <unistd.h>
pid_t getpid(void); //获取当前pid
pid_t getppid(void); //获取父进程pid
*/
printf("用户pid: %d\n", getpid());
printf("父子进程pid: %d\n", getppid());

/*
#include <unistd.h>
#include <sys/types.h>
uid_t getuid(void); //获取当前用户uid
uid_t geteuid(void);//获取当前进程有效uid
gid_t getgid(void); //获取当前用户的gid
gid_t getegid(void);//获取当前进程有效gid
*/

printf("用户uid: %d\n", getuid());
printf("进程有效uid: %d\n", geteuid()); //euid(Effective user id)
printf("用户gid: %d\n", getgid());
printf("进程有效gid: %d\n", getegid());

/*
#include <pwd.h>
#include <sys/types.h>
#include <unistd.h>

struct passwd *info {
char *pw_name; //登录名称
char *pw_passwd; //登录口令
uid_t pw_uid; //用户id
gid_t pw_gid; //用户组id
char *pw_gecos; //用户真名
char *pw_dir; //用户目录
char *pw_shell; //用户shell
};

struct passwd *getpwuid(uid_t uid);
*/

struct passwd *info = NULL;
info = getpwuid(getuid());
printf("%p\n", getpwuid(getuid()));
if(info != NULL) {
printf("Name : %s\n", info->pw_name);
printf("Passwd: %s\n", info->pw_passwd);
printf("Uid : %d\n", info->pw_uid);
printf("Gid : %d\n", info->pw_gid);
printf("Real Name: %s\n", info->pw_gecos);
printf("Home dir : %s\n", info->pw_dir);
printf("Shell : %s\n", info->pw_shell);
}

return 0;
}

创建子进程

头文件

1
2
#include <sys/types.h>
#include <sys/wait.h>

函数

1
2
pid_t wait(int *stat_loc);
pid_t waitpid(pid_t pid, int *stat_loc, int options);

wait 系统调用会使父进程阻塞直到一个子进程结束或者是父进程接受到了一个信号.如果
没有父进程没有子进程或者他的子进程已经结束了 wait 回立即返回.成功时(因一个子进
程结束)wait 将返回子进程的 ID,否则返回-1,并设置全局变量 errno.stat_loc 是子进程的
退出状态.子进程调用 exit,_exit 或者是 return 来设置这个值. 为了得到这个值 Linux 定
义了几个宏来测试这个返回值.
WIFEXITED:判断子进程退出值是非 0
WEXITSTATUS:判断子进程的退出值(当子进程退出时非 0).
WIFSIGNALED:子进程由于有没有获得的信号而退出.
WTERMSIG:子进程没有获得的信号号(在 WIFSIGNALED 为真时才有意义).
waitpid 等待指定的子进程直到子进程返回.如果 pid 为正值则等待指定的进程(pid).如果
为 0 则等待任何一个组 ID 和调用者的组 ID 相同的进程.为-1 时等同于 wait 调用.小于-1 时等
待任何一个组 ID 等于 pid 绝对值的进程. stat_loc 和 wait 的意义一样. options 可以决定
父 进 程 的 状 态 . 可 以 取 两 个 值 WNOHANG : 父 进 程 立 即 返 回 当 没 有 子 进 程 存 在 时 .
WUNTACHE
D:当子进程结束时 waitpid 返回,但是子进程的退出状态不可得到.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>

int main(int argv, char **argc) {

pid_t pid;
int status;
printf("This will demostrate how to get child status\n");
if(-1 == (pid = fork())) {
printf("Fork error: %s\n", strerror(errno)); //与perror差不多
exit(-1);
}else if(pid == 0) { //代表是子进程
int i;
printf("I'm the child : %d\n", getpid());
for(int i = 0; i < 1000000; ++i) { //进行大量计算
sin(i);
}
sleep(50);
i = 4;
printf("I exit with %d\n", i);
exit(i); //以 错误号为4退出
}

/*


*/

while((-1 == (pid = wait(&status))) & (errno == EINTR)); //父进程阻塞,直到子进程结束
if(-1 == pid) {
printf("Wait error: %s\n", strerror(errno));
}else if(!status) {
printf("Child %d terminated normally return status is zero\n");
}else if(WIFEXITED(status)) {
printf("Child %d terminated normally return status is %d\n",
pid, WEXITSTATUS(status));
}else if(WIFSIGNALED(status)) { //子进程是以信号方式退出
printf("Child %d terminated due to signal %d\n",
pid, WTERMSIG(status));
}

return 0;
}

实现demon进程

检查邮箱程序,让子进程在后台运行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>

//linux 默认个人邮箱地址是: /var/spool/mail用户登录名称
#define MAIL "/var/spool/mail/logan/a.com"
#define SLEEP_TIME 2

int main(void) {
pid_t pid;
if(-1 == (pid = fork())) {
printf("Fork error: %s\n", strerror(errno));
exit(1);
}else if(pid > 0)
while(1);

if(kill(getppid(), SIGTERM) == -1){ //杀掉父进程
printf("Kill parent error: %s\n", strerror(errno));
exit(1);
}
int mailfd;
while(1) {
if(-1 != (mailfd = open(MAIL, O_RDONLY))) {
fprintf(stderr,"%s", "\007");
close(mailfd);
}
sleep(SLEEP_TIME);
}

return 0;
}

文件操作

1

打赏点小钱
支付宝 | Alipay
微信 | WeChat