系统编程之进程控制编程(二)

本文详细介绍了进程控制函数如execl(), execlp(), execv(), system(), exit(), _exit(), wait() 和 waitpid()的功能及使用方法。同时,还探讨了如何避免僵尸进程的产生,以及如何创建守护进程。

1、execl():

头文件:#include <unistd.h>

函数原型:int execl(const char *path, const char *arg, ...);

功能:产生一个新程序替换原有的程序执行,原有的进程ID不变。

#include <unistd.h>
#include <stdio.h>

int main()
{
	int ret = execl("/mnt/hgfs/Share/0809/review/bubble_sort", "./file", NULL);
	if(ret == -1)
	{
		perror("execl");
		return -1;
	}
	
	printf("原程序不再执行\n");
	
    return 0;
}

说明:

由于产生了一个新的程序将原有的程序替换所以原有的程序将不再执行,printf也就没有打印输出。


2、execlp():

头文件:#include <unistd.h>

函数原型:int execlp(const char *file, const char *arg, ...);

功能:与execl()基本相同,不同的是如果在规定的目录下找不到执行文件它会去PATH环境变量中查找该程序。

int main()
{
	int ret = execlp("file", "file", NULL);
	if (ret == -1)
	{
		perror("execl");
		return -1;
	}


	return 0;
}


3、execv():

头文件:#include <unistd.h>

函数原型:int execv(const char *path, char *const argv[]);

功能:与execl()基本相同,不同的是它将execl()后面的参数保存在一个字符串指针数组中。

int main()
{
	char *a[] = {"file", NULL};
	int ret = execv("file", a);
	if (ret == -1)
	{
		perror("execl");
		return -1;
	}
	
	
	return 0;
}

4、system():

头文件:#include <stdlib.h>

函数原型:int system(const char *command);

功能:调用fork产生子进程,由子进程来调用 /bin/sh -c string来执行参数string所代表的命令,不会使原进程被替换。

实现一个伪终端:

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

int main()
{
	char str[100];
	
	while(1)
	{
		printf("[root@localhost ~]# ");
		fgets(str,100,stdin);
		system(str);
	}

    return 0;
}


5、exit()和_exit():

_exit: 直接使进程停止,清除其使用的内存,并清除缓冲区中内容。

exit:在停止进程之前,要检查文件的打开情况,并把文件缓冲区中的内容写回文件才停止进程。


子进程比父进程先退出会形成僵尸进程:

父进程调用fork创建子进程后,子进程运行直至其终止,它立即从内存中移除,但进程描述符仍然保留在内存中(进程描述符占有极少的内存空间)。

因此一个僵尸存在于其终止到父进程调用 wait 等函数这个时间的间隙,一般很快就消失,但如果编程不合理,父进程从不调用 wait 等系统调用来收集僵尸进程,那么这些进程会一直存在内存中,直到父进程中断结束。


父进程比子进程先退出:

若父进程比子进程先终止,则该父进程的所有子进程的父进程都改变为init进程。我们称这些进程由init进程领养。其执行顺序大致如下:在一个进程终止时,内核逐个检查所有活动进程,以判断它是否是正要终止的进程的子进程,如果是,则该进程的父进程ID就更改为1(init进程的ID)。

有init领养的进程不会称为僵尸进程,因为只要init的子进程终止,init就会调用一个wait函数取得其终止状态。这样也就防止了在系统中有很多僵尸进程。

守护进程的创建:

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>

int daemon_process()
{
	// 1、创建子进程,关闭父进程
	pid_t pid = fork();
	
	if(pid < 0)
	{
		perror("fork");
		return -1;
	}
	
	else if(pid > 0)
	{
		exit(0);
	}
	
	// 2、设置文件的掩码, mode & ~umask
	umask(0);
	
	// 3、设置新的会话: 脱离当前会话和终端的控制
	if(setsid() < 0)
	{
		perror("setsid");
		return -1;
	}
		
	// 4、改变当前的工作目录
	if(chdir("/") < 0)
	{
		perror("chdir");
		return -1;
	}
	
	// 5、关闭标准输入、标准输出、标准错误
	close(STDIN_FILENO);
	close(STDOUT_FILENO);
	close(STDERR_FILENO);
	
	// 6、重定向标准输入、标准输出、标准错误
	open("/dev/null", O_RDONLY);   // 0 
	open("/dev/null", O_RDWR);   // 1
	open("/dev/null", O_RDWR);   // 2
	
	return 0;
}

int main()
{
	daemon_process();
	
	while(1);
	
    return 0;
}

6、wait()和waitpid():

头文件:#include <sys/wait.h>

函数原型:pid_t wait(int *status);
  pid_t waitpid(pid_t pid, int *status, int options); 

功能:接收退出的子进程,若成功返回进程ID,若出错返回-1。

参数pid为欲等待的子进程识别码:

pid<-1 等待进程组识别码为pid绝对值的任何子进程。

pid=-1 等待任何子进程,相当于wait()。

pid=0 等待进程组识别码与目前进程相同的任何子进程。

pid>0 等待任何子进程识别码为pid的子进程。


















基于径向基函数神经网络RBFNN的自适应滑模控制学习(Matlab代码实现)内容概要:本文介绍了基于径向基函数神经网络(RBFNN)的自适应滑模控制方法,并提供了相应的Matlab代码实现。该方法结合了RBF神经网络的非线性逼近能力和滑模控制的强鲁棒性,用于解决复杂系统控制问题,尤其适用于存在不确定性和外部干扰的动态系统。文中详细阐述了控制算法的设计思路、RBFNN的结构与权重更新机制、滑模面的构建以及自适应律的推导过程,并通过Matlab仿真验证了所提方法的有效性和稳定性。此外,文档还列举了大量相关的科研方向和技术应用,涵盖智能优化算法、机器学习、电力系统、路径规划等多个领域,展示了该技术的广泛应用前景。; 适合人群:具备一定自动控制理论基础和Matlab编程能力的研究生、科研人员及工程技术人员,特别是从事智能控制、非线性系统控制及相关领域的研究人员; 使用场景及目标:①学习和掌握RBF神经网络与滑模控制相结合的自适应控制策略设计方法;②应用于电机控制、机器人轨迹跟踪、电力电子系统等存在模型不确定性或外界扰动的实际控制系统中,提升控制精度与鲁棒性; 阅读建议:建议读者结合提供的Matlab代码进行仿真实践,深入理解算法实现细节,同时可参考文中提及的相关技术方向拓展研究思路,注重理论分析与仿真验证相结合。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值