fork 调用失败则返回-1
//fork 创建一个子进程
#include
#include
int main(void)
{
pid_t pid;
pid = fork();
if(pid == 0){
printf("child\n");
} else {
printf("parent\n");
}
return 0;
}
/*
$ ./fork
parent
child
*/
/*
creat parent child
*/
#include
#include
#include
int main(void)
{
pid_t pid;
char *message;
int n;
pid = fork();
if(pid == -1){
perror("fork error");
exit(1);
}else if(pid == 0){
printf("i'am child, pid = %d\n", getpid());
printf("parent id = %d\n", getppid());
}else if(pid > 0){
printf("parent, pid = %d\n", getpid());
}
return 0;
}
/*akaedu@akaedu-G41MT-D3:~/lin/20140828_fock$ ./4
parent, pid = 7034
i'am child, pid = 7035
parent id = 7034
*/
/*
creat 5 child
循环创建5个子进程
*/
#include
#include
#include
int main(int argc, char *argv[])
{
int n = 5, i; //默认创建5个子进程
if(argc == 2){
n = atoi(argv[1]);
}
for(i = 0; i < n; i++){ //出口1,父进程专用出口
if(fork() == 0)
break; //出口2,子进程出口,i不自增
}
if(n == i){
sleep(i);
printf("parent. pid = %d\n", getpid());
}else {
sleep(i);
printf("%d child. pid = %d\n", i+1, getpid());
}
return 0;
}
/*akaedu@akaedu-G41MT-D3:~/lin/20140828_fock$ ./6
1 child. pid = 7448
2 child. pid = 7449
3 child. pid = 7450
4 child. pid = 7451
5 child. pid = 7452
parent. pid = 7447
*/
//父子进程共享打开的文件,建立的映射区
//不共享:.data malloc stack heap 命令行参数 全局变量
#include
#include
#include
int a = 100;
int main(void)
{
pid_t pid;
pid = fork();
if(pid == 0){ //sun
a = 2000; //子进程修改了a值,父进程不共享修改
printf("child, a = %d\n", a);
} else {
sleep(1); //保证sun先运行
printf("parent, a = %d\n", a);
}
return 0;
}
/*
akaedu@akaedu-G41MT-D3:~/桌面/T74_system/0828_chp3_process_environ_control$ ./fork_shared
child, a = 2000
parent, a = 100
*/
/****推荐****/
/*
父子进程映射区共享
/dev/zero 是一个特殊的文件,当你读它的时候,它会提供无限的空字符(NULL, ASCII NUL, 0x00)。
其中的一个典型用法是用它提供的字符流来覆盖信息,另一个常见用法是产生一个特定大小的空白文件。
BSD就是通过mmap把/dev/zero映射到虚地址空间实现共享内存的。
*/
#include
#include
#include
#include
#include
#define N 4
int main(void)
{
int *p;
pid_t pid;
int fd = open("/dev/zero", O_RDWR);
p = mmap(NULL, N, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if(p == MAP_FAILED){ //注意:不是p == NULL
perror("mmap error");
exit(1);
}
close(fd); //映射完就可以关闭fd
pid = fork(); //创建子进程
if(pid == 0){
*p = 2000;
printf("child, *p = %d\n", *p);
} else {
sleep(1);
printf("parent, *p = %d\n", *p);
}
munmap(p, N); //释放映射区
return 0;
}
/*akaedu@akaedu-G41MT-D3:~/桌面/T74_system/0828_chp3_process_environ_control$ ./fork_map_anon
child, *p = 2000
parent, *p = 2000
*/
//父子进程共享打开的文件,建立的映射区
//方法较老,不推荐
#include
#include
#include
#include
#include
int var = 100;
int main(void)
{
int *p;
pid_t pid;
int fd;
fd = open("temp", O_RDWR|O_CREAT|O_TRUNC, 0644);
if(fd < 0){
perror("open error");
exit(1);
}
unlink("temp"); //删除临时文件目录项
lseek(fd, 3, SEEK_SET); //open的文件长度0,不能直接建映射区
write(fd, "a", 1); //引起IO操作,物理上拓展文件
p = (int *)mmap(NULL, 4, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
if(p == MAP_FAILED){ //注意:不是p == NULL
perror("mmap error");
exit(1);
}
close(fd); //映射区建立完毕,即可关闭文件
pid = fork(); //创建子进程
if(pid == 0){
*p = 2000;
var = 1000;
printf("child, *p = %d, var = %d\n", *p, var);
} else {
sleep(1);
printf("parent, *p = %d, var = %d\n", *p, var);
}
munmap(p, 4); //释放映射区
return 0;
}
/*akaedu@akaedu-G41MT-D3:~/桌面/T74_system/0828_chp3_process_environ_control$ ./fork_mmap
child, *p = 2000, var = 1000
parent, *p = 1627389952, var = 100
*/