单道程序 多道程序设计 Timeslice Parallel: multiprocessors Concurrency: single processor PCB: Processing Control Block struct task_struct
1 2 3 4 5 6 7 8 9 10 11 12 13 14
structtask_struct{ intpid_t; //进程状态 // 保存和恢复的一些CPU寄存器 //虚拟地址空间 //控制终端的信息 //current working directory // umask // file describer // signal related infor // uid gid // session and process group // }
1 2
ulimit -a ulimit -n
进程状态转换
三态模型:就绪、运行、阻塞 五态模型:新建、就绪、运行、阻塞、终止
1 2
$ ps aux $ ps j
arg
usage
a
all
u
详细信息
x
没有控制终端的进程
j
作业进程
1 2 3
$ top $ kill //kill process $ ./a.out & #后代运行
1 2 3
pid_tgetpid(void); pid_tgetppid(void); // father pid pid_tgetpgid(pid_t pid); //
intmain() { pid_t pid; for (int i=0; i<5; i++) { pid = fork(); if (pid==0) break; } if (pid>0) { while (1) { printf("I'm parent, pid:%d\n", getpid()); int st; int ret = wait(&st); if (ret==-1) break; printf("exited with %d\n", WTERMSIG(st)); printf("child die, pid:%d\n", ret); sleep(1); } }elseif (pid==0) { while(1) { printf("I'm child process, pid:%d, ppid:%d\n", getpid(), getppid()); sleep(1); } } return0; }
waitpid 函数
可以设置是否阻塞
The value of pid can be: < -1 meaning wait for any child process whose process group ID is equal to the absolute value of pid. -1 meaning wait for any child process. 0 meaning wait for any child process whose process group ID is equal to that of the calling process. 0 meaning wait for the child whose process ID is equal to the value of pid. The value of options is an OR of zero or more of the following con‐ stants: WNOHANG return immediately if no child has exited. WUNTRACED also return if a child has stopped (but not traced via ptrace(2)). Status for traced children which have stopped is provided even if this option is not specified. WCONTINUED (since Linux 2.6.10) also return if a stopped child has been resumed by delivery of SIGCONT. waitpid(): on success, returns the process ID of the child whose state has changed; if WNOHANG was specified and one or more child(ren) speci‐ fied by pid exist, but have not yet changed state, then 0 is returned. On error, -1 is returned.
#include<unistd.h> /*create pipe */ intpipe(int pipefd[2]); /* show pipe buffer limit */ longfpathconf(int fd, int name);
1 2
# pipe size ulimit -a
父子进程通过匿名管道通信
1 2 3 4 5 6 7 8 9 10 11 12 13
#include<unistd.h> intpipe(int pipefd[2]); /** pipe() creates a pipe, a unidirectional data channel that can be used for interprocess communication. The array pipefd is used to return two file descriptors referring to the ends of the pipe. pipefd[0] refers to the read end of the pipe. pipefd[1] refers to the write end of the pipe. Data written to the write end of the pipe is buffered by the kernel until it is read from the read end of the pipe. @param[out] pipefd[0] read end @param[out] pipefd[1] write end @return 0 success, -1 failed */
#include <sys/mman.h> void *mmap(void addr, size_t length, int prot, int flags, int fd, off_t offset); int munmap(void addr, size_t length); / 释放内存映射 / / mmap() creates a new mapping in the virtual address space of the call‐ ing process. The starting address for the new mapping is specified in addr. The length argument specifies the length of the mapping (which must be greater than 0). If addr is NULL, then the kernel chooses the address at which to create the mapping; this is the most portable method of creating a new map‐ ping. If addr is not NULL, then the kernel takes it as a hint about where to place the mapping; on Linux, the mapping will be created at a nearby page boundary. The address of the new mapping is returned as the result of the call. The contents of a file mapping (as opposed to an anonymous mapping; see MAP_ANONYMOUS below), are initialized using length bytes starting at offset offset in the file (or other object) referred to by the file descriptor fd. offset must be a multiple of the page size as returned by sysconf(_SC_PAGE_SIZE). The prot argument describes the desired memory protection of the map‐ ping (and must not conflict with the open mode of the file). It is either PROT_NONE or the bitwise OR of one or more of the following flags: PROT_EXEC Pages may be executed. PROT_READ Pages may be read. PROT_WRITE Pages may be written. PROT_NONE Pages may not be accessed. */
intkill(pid_t pid, int sig); /* If pid is positive, then signal sig is sent to the process with the ID specified by pid. If pid equals 0, then sig is sent to every process in the process group of the calling process. If pid equals -1, then sig is sent to every process for which the call‐ ing process has permission to send signals, except for process 1 (init), but see below. If pid is less than -1, then sig is sent to every process in the process group whose ID is -pid. */
#include<signal.h> intraise(int sig); /* The raise() function sends a signal to the calling process or thread. In a single-threaded program it is equivalent to */ #include<stdlib.h> voidabort(void);
int ret = setitimer(ITIMER_REAL, &new_value, NULL); printf("Itimer start.\n"); if (ret==-1) { perror("setitimer"); exit(0); }
getchar(); return0; }
signal 信号捕捉函数
1 2 3 4 5
#include<signal.h>
typedefvoid(*sighandler_t)(int); sighandler_tsignal(int signum, sighandler_t handler); /* The signals SIGKILL and SIGSTOP cannot be caught or ignored. */
intmain() { sigset_tset; sigemptyset(&set); int ret = sigismember(&set, SIGINT); if (ret==0) printf("SIGINT not block\n"); if (ret==1) printf("SIGINT block\n"); sigaddset(&set, SIGINT); sigaddset(&set, SIGQUIT); ret = sigismember(&set, SIGINT); if (ret==0) printf("SIGINT not block\n"); if (ret==1) printf("SIGINT block\n");
sigdelset(&set, SIGQUIT); ret = sigismember(&set, SIGQUIT); if (ret==0) printf("SIGQUIT not block\n"); if (ret==1) printf("SIGQUIT block\n");
voidmyFun(int num) { printf("caught signal: %d\n", num); //TO DO while(1) { int ret = waitpid(-1, NULL, WNOHANG); if (ret>0) printf("caught child %d\n", ret); elseif (ret==0) { printf("caught no child process\n"); break; }else{ break; } } }
intmain() { //block signal before fork, in case child process died before signal registration. sigset_tset; sigemptyset(&set); sigaddset(&set, SIGCHLD); sigprocmask(SIG_BLOCK, &set, NULL); pid_t pid; for (int i=0; i<10; i++) { pid = fork(); if (pid==0) break; }