1. 进程如何创建
- 利用fork函数创建进程.
- fork正常创建进程成功后, 会有两个返回值表现为两个进程(0: 子进程; 1:父进程), 其它则出错.
2. 父子进程之间的关系
- 子进程继承父进程fork之前的所有特征
- 父进程和子进程有自己独立的PCB(进程控制块)
- 父进程和子进程一旦创建便为就绪态, 待CPU进行同等优先级进行调度
- 父进程和子进程存在竞态情况, 一旦fork后马上运行的情况下, 不确定父进程或子进程被优先调度
3. 父子进程操作同一个文件的情况
- 父进程打开一个文件后得到fd, 在fork后被子进程继承, 可实现对文件的接续操作.
/* 一个进程打开一个文件, 然后fork一个子进程, 子进程继承了父进程的fd */
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#define PATHNAME "1.txt"
int main(int argc, char *argv[])
{
pid_t pid = -1;
int fd = -1;
fd = open(PATHNAME, O_RDWR);
pid = fork();
if(pid > 0){
/* parent process */
printf("parent process running..., pid = %d\n", getpid());
write(fd, "hello", 5);
}else if(0 == pid)
{
/* child process */
printf("child process running..., pid = %d\n", getpid());
write(fd, "world", 5);
}else{
perror("fork");
return -1;
}
return 0;
}
2. 父进程和子进程分别打开同一个文件后进行写操作, 实现的是独立写.
/* fork之后,父子进程分别打开同一个文件进行操作, 为独立操作 */
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#define PATHNAME "1.txt"
int main(int argc, char *argv[])
{
pid_t pid = -1;
int fd1 = -1;
int fd2 = -1;
pid = fork();
if(pid > 0){
/* parent process */
printf("parent process running..., pid = %d\n", getpid());
fd1 = open(PATHNAME, O_RDWR);
if(fd1 < 0){
perror("parent open");
_exit(-1);
}
write(fd1, "hello", 5);
}else if(0 == pid)
{
/* child process */
printf("child process running..., pid = %d\n", getpid());
fd2 = open(PATHNAME, O_RDWR);
if (fd2 < 0)
{
perror("child open");
_exit(-1);
}
write(fd2, "world", 5);
}else{
perror("fork");
return -1;
}
return 0;
}
3. 父进程和子进程分别打开同一个文件后进行写操作, 打开文件时使用O_APPEND, 实现的是接续写.
/* fork之后,父子进程分别打开同一个文件进行写操作且打开文件时使用O_APPEND, 为接续写 */ #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> #define PATHNAME "1.txt" int main(int argc, char *argv[]) { pid_t pid = -1; int fd1 = -1; int fd2 = -1; pid = fork(); if(pid > 0){ /* parent process */ printf("parent process running..., pid = %d\n", getpid()); fd1 = open(PATHNAME, O_RDWR | O_APPEND); if(fd1 < 0){ perror("parent open"); _exit(-1); } write(fd1, "hello", 5); }else if(0 == pid) { /* child process */ printf("child process running..., pid = %d\n", getpid()); fd2 = open(PATHNAME, O_RDWR | O_APPEND); if (fd2 < 0) { perror("child open"); _exit(-1); } write(fd2, "world", 5); }else{ perror("fork"); return -1; } return 0; }
4. 小结: open函数使用时, 如果不带O_TRUNC及O_APPEND的flag时, 写文件时默认使用O_TRUNC方式写.