2-12 多进程程序设计
2016-09-13 09:36
127 查看
(本节笔记接上一节的进程控制,继续学习多进程的程序设计函数,详细的实验代码在这里)
1. 创建进程
函数名:
fork
函数原型:
pid_t fork ( void );
函数功能:
创建一个子进程
所属头文件:
<unistd.h>
返回值:
成功:在父进程中返回子进程的pid,在子进程中返回0 失败:返回1
参数说明:
void
范例代码:(touch myfork.c)
#include <unistd.h>
#include <stdio.h>
int main(int argc, char ** argv)
{
fork();
printf("Program is end!\n");
exit(0);
}
输出结果:Program is end!
Program is end!
分析:当父进程调用fork创建一个代码与父进程一样的子进程是,子进程由printf开始执行!(重要)
pid的返回值代码:
#include <unistd.h>
#include <stdio.h>
int main(int argc, char ** argv)
{
pid_t pid = fork();
printf("pid is %d!\n");
exit(0);
}
输出结果:pid is 19112!
pid is 0
让父进程执行分支的方法:
#include <unistd.h>
#include <stdio.h>
int main(int argc, char ** argv)
{
pid_t pid = fork();
if ( pid > 0) /* parent process */
{
printf("here is parent process!\n");
}
else /* child process */
{
printf("here is child process.\n");
}
exit(0);
}
2. 创建进程的另一种方式
函数名:
vfork
函数原型:
pid_t vfork ( void );
函数功能:
创建一个子进程,并阻塞父进程
所属头文件:
<sys/types.h> <unistd.h>
返回值:
成功:在父进程返回子进程的ID,在子进程返回0
参数说明:
void
范例代码:(touch myvfork.c)
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main ( int argc, char ** argv)
{
pid_t pid = vfork();
if ( pid > 0)
{
printf("father\n");
exit(0);
}
else
{
printf("child\n);
exit(0);
}
}
程序输出的结果:child
father
分析——fork与fork的区别:vfork会阻塞父进程,子进程优先运行,而fork的父子进程的运行顺序是随机的
范例代码2:(touch forkcount.c)
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main ( int argc, char ** argv)
{
int count = 0;
pid_t pid = vfork();
count++;
printf("%d\n", count);
exit(0);
}
程序输出的结果:1
1
分析——在调用fork()创建的子进程中的栈是完全复制了父进程的栈,而且与父进程的栈相互独立。而vfork()创建的子进程与父进程共享同一个栈。
3. 进程的退出
父进程:可用return 0 , 也可用exit(0);
子进程:只能使用exit(0);
4. 进程等待
函数名:
wait
函数原型:
pid_t wait ( int *status);
函数功能:
挂起调用它的进程,直到其子进程结束
所属头文件:
<sys/types.h> <sys/wait.h>
返回值:
成功:返回中止的那个进程的PID 失败:返回-1
参数说明:
status:记录子进程的退出状态。
范例代码:(touch mywait.c)
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
int main( int argc, char ** argv)
{
pid_t pid = fork();
if ( pid > 0)
{
wait ( NULL );
printf( "father\n");
exit(0);
}
else
{
printf("child\n");
exit(0);
}
}
4. 程序执行
函数名:(execl、execv、execle、execve、execlp、execvp)
execl
函数原型:
int execl ( const char *path, const char *arg, ...);
函数功能:
运行可执行文件
所属头文件:
<unistd.h>
返回值:
成功:无返回 失败:返回-1 (关于execl的返回值问题,可参考以下这里)
参数说明:
path:要运行的可执行程序的路径
arg:作为该可执行程序的参数,直接以NULL为参数结束标志
范例代码:
..........
execl("/bin/ls", "ls", "/home", NULL);
..........
(一旦调用了execl(),原进程代码段将被execl创建的可执行程序锁替换,例如以下两行代码:
execl(......);
printf(......);
printf的操作始终不会被执行)
1. 创建进程
函数名:
fork
函数原型:
pid_t fork ( void );
函数功能:
创建一个子进程
所属头文件:
<unistd.h>
返回值:
成功:在父进程中返回子进程的pid,在子进程中返回0 失败:返回1
参数说明:
void
范例代码:(touch myfork.c)
#include <unistd.h>
#include <stdio.h>
int main(int argc, char ** argv)
{
fork();
printf("Program is end!\n");
exit(0);
}
输出结果:Program is end!
Program is end!
分析:当父进程调用fork创建一个代码与父进程一样的子进程是,子进程由printf开始执行!(重要)
pid的返回值代码:
#include <unistd.h>
#include <stdio.h>
int main(int argc, char ** argv)
{
pid_t pid = fork();
printf("pid is %d!\n");
exit(0);
}
输出结果:pid is 19112!
pid is 0
让父进程执行分支的方法:
#include <unistd.h>
#include <stdio.h>
int main(int argc, char ** argv)
{
pid_t pid = fork();
if ( pid > 0) /* parent process */
{
printf("here is parent process!\n");
}
else /* child process */
{
printf("here is child process.\n");
}
exit(0);
}
2. 创建进程的另一种方式
函数名:
vfork
函数原型:
pid_t vfork ( void );
函数功能:
创建一个子进程,并阻塞父进程
所属头文件:
<sys/types.h> <unistd.h>
返回值:
成功:在父进程返回子进程的ID,在子进程返回0
参数说明:
void
范例代码:(touch myvfork.c)
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main ( int argc, char ** argv)
{
pid_t pid = vfork();
if ( pid > 0)
{
printf("father\n");
exit(0);
}
else
{
printf("child\n);
exit(0);
}
}
程序输出的结果:child
father
分析——fork与fork的区别:vfork会阻塞父进程,子进程优先运行,而fork的父子进程的运行顺序是随机的
范例代码2:(touch forkcount.c)
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main ( int argc, char ** argv)
{
int count = 0;
pid_t pid = vfork();
count++;
printf("%d\n", count);
exit(0);
}
程序输出的结果:1
1
分析——在调用fork()创建的子进程中的栈是完全复制了父进程的栈,而且与父进程的栈相互独立。而vfork()创建的子进程与父进程共享同一个栈。
3. 进程的退出
父进程:可用return 0 , 也可用exit(0);
子进程:只能使用exit(0);
4. 进程等待
函数名:
wait
函数原型:
pid_t wait ( int *status);
函数功能:
挂起调用它的进程,直到其子进程结束
所属头文件:
<sys/types.h> <sys/wait.h>
返回值:
成功:返回中止的那个进程的PID 失败:返回-1
参数说明:
status:记录子进程的退出状态。
范例代码:(touch mywait.c)
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
int main( int argc, char ** argv)
{
pid_t pid = fork();
if ( pid > 0)
{
wait ( NULL );
printf( "father\n");
exit(0);
}
else
{
printf("child\n");
exit(0);
}
}
4. 程序执行
函数名:(execl、execv、execle、execve、execlp、execvp)
execl
函数原型:
int execl ( const char *path, const char *arg, ...);
函数功能:
运行可执行文件
所属头文件:
<unistd.h>
返回值:
成功:无返回 失败:返回-1 (关于execl的返回值问题,可参考以下这里)
参数说明:
path:要运行的可执行程序的路径
arg:作为该可执行程序的参数,直接以NULL为参数结束标志
范例代码:
..........
execl("/bin/ls", "ls", "/home", NULL);
..........
(一旦调用了execl(),原进程代码段将被execl创建的可执行程序锁替换,例如以下两行代码:
execl(......);
printf(......);
printf的操作始终不会被执行)
相关文章推荐
- 练习1-12:编写一个程序,以每行一个单词的形式打印其输入(C程序设计语言 第2版)
- 【C++程序设计语言A视频教程 全12讲 中科院】【下载链接】
- 计算机学院大学生程序设计竞赛(2015’12)The Magic Tower
- 计算机学院大学生程序设计竞赛(2015’12) 1002 Polygon
- 杭州电子科技大学计算机学院大学生程序设计竞赛(2015'12)Bitwise Equations (二进制)
- c程序设计语言 习题1-12
- BIT2014级软件学院程序设计-12 编程珠玑
- HDU 程序设计竞赛题解(2016‘12)
- 第八届福建省大学生程序设计竞赛训练总结【7/12】
- 杭州电子科技大学程序设计竞赛(2016’12)- 网络同步赛 1007
- 07-多进程程序设计
- 计算机学院大学生程序设计竞赛(2015’12)Study Words
- 计算机学院大学生程序设计竞赛(2015’12) 1003 The collector’s puzzle
- 计算机学院大学生程序设计竞赛(2015’12)1001 The Country List
- 计算机学院大学生程序设计竞赛(2015’12)(STL )
- 基础知识(12)- 泛型程序设计
- 12. javacript高级程序设计-DOM2和DOM3
- 2013-BIT程序设计 12.编程珠玑 -- dp
- MFC Windows程序设计 12-1
- hdu 计算机学院大学生程序设计竞赛(2015’12)The Country List