Linux期末复习——进程控制开发

进程概述

        进程基本概念

                定义:正在进行(执行)的程序

                进程三种状态的转化关系

                

        进程控制编程 

                fork()函数

                功能:创建一个子进程,子进程是父进程复制品,返回值有两个,父进程中返回进程号,子进程返回0。

                缺点:开销大,速度慢

                示例代码:

/* fork.c */
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	pid_t result;	
	
	result = fork();/*调用fork函数,其返回值赋值给result*/	
	
	if(result ==  -1)/*通过result的值来判断fork函数的返回情况,首先进行出错处理*/
	{
		printf("Fork error\n");
	}
	else if (result == 0) /*返回值为0代表子进程*/
	{
		printf("The return value is %d\nIn child process!!\nThe child process PID is %d\n\n",result,getpid());
	}
	else /*返回值大于0代表父进程*/
	{
		printf("The return value is %d\nIn father process!!\nThe father process PID is %d\n",result,getpid());
	}
	
	return result;
}

                exec函数族

                        Linux中没有exec()函数,这里是六个以exec开头的函数

                        

前四位均为exec
第五位
l参数传递像列表一样逐个列举execl()、execle()、execlp()
v参数传递通过指针数组传递execv()、execve()、execvp()

第六位
e可传递新进程环境变量execle()、execve()
p可执行文件查找方式为文件名execlp()、execvp()

                exit()和_exit()函数

                        二者都是用来终止进程的。

                        区别:exit()调用exit系统之前会把文件缓冲区的内容协会文件

                        exit()示例代码:   

/* exit.c 由于printf()函数使用的是缓冲I/O 方式,该函数在遇到“\n”换行符时自动从缓冲区中将记录读出。
示例中就是利用这个性质来进行比较的。
*/

#include <stdio.h>
#include <stdlib.h>

int main()
{
  	  printf("Using exit...\n");
  	  printf("This is the content in buffer");
  	  exit(0);
}

             

      _exit()示例代码:


#include <stdio.h>

#include <unistd.h>



int main()

{

  	  printf("Using _exit...\n");

  	  printf("This is the content in buffer");

  	  _exit(0);

}

 调用exit()函数的时候缓冲区能正常输出,_exit()无法输出缓冲区记录

wait()和waitpid()函数

        作用:用于阻塞父进程

        区别:waitpid不一定要等待第一个终止的子进程

        示例代码:

/* waitpid.c */

#include <sys/types.h>

#include <sys/wait.h>

#include <unistd.h>

#include <stdio.h>

#include <stdlib.h>



int main()

{

	pid_t pc, pr;

	

	pc = fork();

	if (pc < 0)

	{

		printf("Error fork\n");

	}

	else if (pc == 0) /*子进程*/

	{ 

		/*子进程暂停5s*/

                printf("The Child process is going to sleep(5);\n");

		sleep(5);

		printf("The Child process wake up;\n");

		/*子进程正常退出*/

		exit(0);

	}

	else /*父进程*/

	{

		/*循环测试子进程是否退出*/

		do

		{

			/*调用waitpid,且父进程不阻塞*/
            /*WNOHANG就是不阻塞的意思*/

			pr = waitpid(pc, NULL, WNOHANG);





			

			/*若子进程还未退出,则父进程暂停1s*/

			if (pr == 0)

			{

				printf("The child process has not exited\n");

                                

				sleep(1);

			}

		} while (pr == 0);

		

		/*若发现子进程退出,则waitpid()返回值为子进程进程号*/

		if (pr == pc)

		{

                        printf("\nThe father process quit because the child process quit.\n");

                        printf("The return of waitpid() is the child process PID  : %d\n",pr);

			

		}

		else

		{

			printf("Some error occured.\n");

		}

	}

	

	return 0;

}

守护进程

什么是守护进程?

独立于控制终端,周期性执行某种任务或者等待处理某些发生的事件的特殊进程

守护进程编写步奏

1.创建子进程,父进程退出     

        pid = fork();//获取fork函数返回的返回值

        if(pid>0)//如果是进程号说明是父进程

        {
           exit(0);//退出

         }

2.在子进程中创建新的会话

        使用setsid()函数创建一个新的会话

        作用:让进程摆脱(原会话,原进程组,原控制终端)

3.改变当前目录为根目录

        使用chdir("/")函数更改工作目录到根目录

4.重设文件权限掩码

        umask(0)

5.关闭文件描述符

        close()

示例代码:

/* dameon.c 创建守护进程实例 */

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <fcntl.h>

#include <sys/types.h>

#include <unistd.h>

#include <sys/wait.h>

#include <syslog.h>



int main()

{

	pid_t pid;

	int   i, fd;

	char  *buf = "This is a Daemon\n";

	

	pid = fork(); /* 第一步 创建子进程,父进程退出*/

	if (pid < 0)

	{

		printf("Error fork\n");

		exit(1);

	}

	else if (pid > 0)

	{

		exit(0); /* 父进程退出 */

	}

			

	setsid(); /*第二步 为子进程创建新会话并担任组长*/

	

	chdir("/"); /*第三步 改变当前目录为根目录*/

	

	umask(0); /*第四步 设置文件权限为666*/

/*  

文件权限掩码umask是指屏蔽掉文件权限中的对应位。



比如文件权限掩码050,5=4+1即r和x权限,5出现在第2位,说明是该文件同组的其他用户对该文件具有的读和可执行权限。



chmod是设哪个位,哪么哪个位就有权限,而umask是设哪个位,则哪个位上就没权限。



所以文件掩码050就屏蔽了文件组拥有者的可读与可执行权限。

*/

	

	for(i = 0; i < getdtablesize(); i++) /*第五步 关闭文件描述符;getdtablesize()表示进程所能打开的最大文件数*/

	{

		close(i);

	}

	

	/*这时创建完守护进程,以下开始正式进入守护进程工作*/

	while(1)

	{

		if ((fd = open("/tmp/daemon.log", O_CREAT|O_WRONLY|O_APPEND, 0600)) < 0)

		{

			printf("Open file error\n");

			exit(1);

		}

		

		write(fd, buf, strlen(buf) + 1); /*每隔10秒向/tmp/daemon.log文件写入字符串:This is a Daemon\n*/

		close(fd);

		sleep(10);

	}

	

	exit(0);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值