1.6程序和进程(shell1.c)

注:部分代码来至《unix高级环境编程》一书。

源码如下:

#include "apue.h"
#include <sys/wait.h>

int
main(void)
{
	char	buf[MAXLINE];	/* from apue.h */
	pid_t	pid;
	int		status;

	printf("%% ");	/* print prompt (printf requires %% to print %) */
	while (fgets(buf, MAXLINE, stdin) != NULL) {
		if (buf[strlen(buf) - 1] == '\n')
			buf[strlen(buf) - 1] = 0; /* replace newline with null */

		if ((pid = fork()) < 0) {
			err_sys("fork error");
		} else if (pid == 0) {		/* child */
			execlp(buf, buf, (char *)0);
			err_ret("couldn't execute: %s", buf);
			exit(127);
		}

		/* parent */
		if ((pid = waitpid(pid, &status, 0)) < 0)
			err_sys("waitpid error");
		printf("%% ");
	}
	exit(0);
}

1、fgets函数使用方法说明

C 库函数 char *fgets(char *str, int n, FILE *stream) 从指定的流 stream 读取一行,并把它存储在 str 所指向的字符串内。当读取 (n-1) 个字符时,或者读取到换行符时,或者到达文件末尾时,它会停止,具体视情况而定。

声明
下面是 fgets() 函数的声明。

char *fgets(char *str, int n, FILE *stream)
参数
str -- 这是指向一个字符数组的指针,该数组存储了要读取的字符串。
n -- 这是要读取的最大字符数(包括最后的空字符)。通常是使用以 str 传递的数组长度。
stream -- 这是指向 FILE 对象的指针,该 FILE 对象标识了要从中读取字符的流。
返回值
如果成功,该函数返回相同的 str 参数。如果到达文件末尾或者没有读取到任何字符,str 的内容保持不变,并返回一个空指针。

如果发生错误,返回一个空指针。

2、execlp 函数使用方法说明

execlp
从PATH 环境变量中查找文件并执行

定义:
int execlp(const char * file,const char * arg,……);

头文件:
#include<unistd.h>

说明:
execlp()会从PATH 环境变量所指的目录中查找符合参数file的文件名, 找到后便执行该文件, 然后将第二个以后的参数当做该文件的argv[0]、argv[1]……, 最后一个参数必须用空指针(NULL)作结束。

返回值:
如果执行成功则函数不会返回, 执行失败则直接返回-1, 失败原因存于errno 中。

相关函数:
fork, execl, execle, execv, execve, execvp

错误代码:
参考execve()。

示例:
#include<unistd.h>

main()
{
execlp("ls","ls","-al","/zhmc",(char *)0);
}

输出:

3、waitpid 函数使用方法说明

用于父进程等待子进程结束。

pid>0时,只等待进程ID等于pid的子进程,不管其它已经有多少子进程运行结束退出了,只要指定的子进程还没有结束,waitpid就会一直等下去。
pid=-1时,等待任何一个子进程退出,没有任何限制,此时waitpid和wait的作用一模一样。
pid=0时,等待同一个进程组中的任何子进程,如果子进程已经加入了别的进程组,waitpid不会对它做任何理睬。
pid<-1时,等待一个指定进程组中的任何子进程,这个进程组的ID等于pid的绝对值。

4、fork函数的使用说明

fork函数用来创建一个子进程。

每个进程都有它独自占有的PCB结构体,而我们通过fork。就是将进程复制了一份
1.父进程和子进程是共享一块代码段的,也就是说同样的代码,父进程和子进程个执行一遍。
2.父进程和子进程数据独自占有,不共享。这就是为什么父进程和子进程同样的代码,却打印出两个不同的val值。
3.fork函数很神奇。它有两个返回值,父进程的返回值是子进程的id号,而子进程自己返回则返回零。失败返回-1.所以我们可以通过介绍fork()返回值来区分父进程子进程,还可以在子进程进行一些特殊操作。

注意:子父进程就像是交替运行一样。

5、下面创建2个子进程

#include "apue.h"
#include <sys/wait.h>
int main(void)
{
printf("before fork(), pid = %d\n", getpid());
pid_t p1 = fork();
if( p1 == 0 )
{
printf("in child 1, pid = %d\n", getpid());
return 0; //若此处没有return 0 p1 进程也会执行 pid_t p2=fork()语句
}
pid_t p2 = fork();
if( p2 == 0 )
{
printf("in child 2, pid = %d\n", getpid());
return 0; //子进程结束,跳回父进程
printf("hello world\n");//没有打印
}
int st1, st2;
waitpid( p1, &st1, 0);
waitpid( p2, &st2, 0);
printf("in parent, child 1 pid = %d\n", p1);
printf("in parent, child 2 pid = %d\n", p2);
printf("in parent, pid = %d\n", getpid());
printf("in parent, child 1 exited with %d\n", st1);
printf("in parent, child 2 exited with %d\n", st2);
return 0;
}

编译运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yfw&武

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值