数组,父子进程,守护进程

2015.1.25
星期日,阴天

二维数组a中共有m行n列个元素
从a[0][0]到a[i][j]之间共有i*n+j个元素
p代表第0行第0列的地址,所以元素a[i][j]的地址为 p + i*n+j

a[i][j] == p[i*n+j] == *(p + i*n+j)

在Linux中获得当前进程的PID和PPID的系统调用函数为getpid()和getppid();获得当前PID和PPID后可以将其写入日志备份!

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
printf("the pid of this process is %d\n",getpid());
printf("the ppid of this process is %d\n",getppid());

}
上面程序可以交叉编译下载到目标板上运行!

父进程调用fork()函数就创建了一个子进程,父进程返回子进程的PID,子进程返回值为0;
fork()函数开销很大,不能多次使用。

exec函数族提供了一个在进程中启动另一个进程执行的方法,总共有6个成员函数,使用exec函数时一定
要加上错误判断语句。exec很容易执行失败。

守护进程:daemon ,从被执行开始运转,直到真个系统关闭时才退出!

编写守护进程:

1.创建子进程,然后父进程退出!
pid = fork();
if(pid > 0)
{
exit(0);/*父进程退出*/
}

2.在子进程中创建新会话:重要一步,意义重大! setsid();

3.改变当前目录为根目录 :让子进程脱离父进程的文件工作目录。

4.重设文件权限掩码: 让子进程脱离父进程的文件权限掩码。

如:050 它就屏蔽了文件组拥有者的可读和可执行权限。用函数umask()实现
通常的使用方法是:umask(0)

5.关闭文件描述符

创建一个守护进程的完整实例:创建守护进程,然后让该进程每隔10S向日志文件/tmp/daemon.log写入一句话。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcn1.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.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); 第四步
for(i = 0; i < getdtablesize(); i++) 第五步
{
close(i);
}

/*这时创建完守护进程,以下开始正式进入守护进程工作*/
while(1)
{
if((fd = open("/tmp/daemon.log",O_CREAT|OWRONLY|O_APPEND.0600))<0)
{
printf("open file error\n");
exit(1);
}
write(fd,buf,strlen(buf) + 1);
close(fd);
sleep(10);
}
exit(0);
}

守护进程出错处理:

gdb无法调试守护进程,因为已经脱离终端,一种通用的办法就是使用syslog服务,将
程序中的出错信息输入到系统日志文件中;

该机制相关的三个syslog函数:openlog();syslog();closelog();
将上面的程序用syslog服务重写;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcn1.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.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); 父进程退出
}

openlog("daemon_syslog",LOG_PID,LOG_DAEMON);

if((sid = setsid() < 0); 第二步
{
syslog(LOG_ERR,%s\n","setsid");
exit(1);
}

if((sid = chdir("/") < 0); 第三步
{
syslog(LOG_ERR,%s\n","chdir");
exit(1);
}
umask(0); 第四步
for(i = 0; i < getdtablesize(); i++) 第五步
{
close(i);
}

/*这时创建完守护进程,以下开始正式进入守护进程工作*/
while(1)
{
if((fd = open("/tmp/daemon.log",O_CREAT|OWRONLY|O_APPEND.0600))<0)
{
syslog(LOG_ERR,"open“);
exit(1);
}
write(fd,buf,strlen(buf) + 1);
close(fd);
sleep(10);
}
closelog();
exit(0);
}

实验内容:
有三个进程,其中一个为父进程,其余两个是该父进程的子进程。其中一个子进程运行
”ls -l“指令,另一个进程暂停5秒之后异常退出,父进程先用阻塞方式等待第一个子进程的结束,
然后用非阻塞方式等待另一个进程的退出,待收集到第二个子进程结束的信息,父进程就返回!

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

int main(void)
{
pid_t child1, child2, child;

/*创建两个子进程*/
child1 = fock();
child2 = fock();

/*子进程1的出错处理*/
if(child1 == -1)
{
printf("child1 fork error\n");
exit(1);
}
else if(child1 == 0) /*在子进程1中调用execlp()函数*/
{
printf("in child1:execute ‘ls -l‘\n");
if(execlp("ls","ls","-1",NULL) < 0)
{
printf("child1 execlp error\n");
}
}

if(child2 == -1) 子进程2出错处理
{
printf("child2 fork error\n");
exit(1);
}
else if(child2 == 0) 在子进程2中使其暂停5秒
{
printf("in child2:sleep for 5 seconds and then exit\n");
sleep(5);
exit(0);
}
else 在父进程中等待两个子进程的退出
{
printf("in father process:\n");
child = waitpid(child1,NULL,0); 阻塞式等待
if(child == child1)
{
printf("get child1 exit code\n");
}
else
{
printf("error occured!\n");
}

do
{
child = waitpid(child2,NULL,WNOHANG); 非阻塞是等待
if(child == 0)
{
printf("the child2 process has not exited!\n");
sleep(1);
}
}while(child == 0);

if(child == child2)
{
printf("get child2 exit code\n");
}
else
{
printf("error occured!\n");
}
}
exit(0);
}

实验内容:
首先建立起一个守护进程,然后在该守护进程中新建一个子进程,该子进程暂停10秒,
然后自动退出,并由守护进程收集子进程退出的消息,在这里,子进程和守护进程的退出消息都在
系统日志文件中输出,子进程退出后,守护进程循环暂停,其间隔时间为10秒。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <syslog.h>

int main(void)
{
pid_t child1, child2;
int i;
/*创建子进程*/
child1 = fork();
if(child1 == 1)
{
perror("child1 fork");
exit(1);
}

else if(child1 > 0)
{
exit(0); 父进程退出
}

openlog("daemon_proc_info",LOG_PID,LOG_DAEMON);
/*下面几步是编写守护进程的常规步骤*/
setsid();
chdir("/");
umask(0);
for(i = 0; i < getdtablesize(); i++)
{
chose(i);
}

child2 = fork(); 创建进程2
if(child2 == 1)
{
perror("child2 fork");
exit(1);
}
else if(child2 == 0) 进入进程2
{
syslog(LOG_INFO,"child2 will sleep for 10s"); 在日志中写入字符串
sleep(10);
syslog(LOG_INFO,"child2 is going to exit!"):
exit(0);
}
else
{ 进程child1

waitpid(child2,NULL,0);
syslog(LOG_INFO,"child1 noticed that child2 has exitde");
closelog(); 关闭日志服务
while(1)
{
sleep(10);
}
}

}

**********************************************************************************************************************************************************
**********************************************************************************************************************************************************
**********************************************************************************************************************************************************

时间: 2024-12-24 12:39:42

数组,父子进程,守护进程的相关文章

开启子进程的两种方式,孤儿进程与僵尸进程,守护进程,互斥锁,IPC机制,生产者与消费者模型

开启子进程的两种方式 # # # 方式一: # from multiprocessing import Process # import time # # def task(x): # print('%s is running' %x) # time.sleep(3) # print('%s is done' %x) # # if __name__ == '__main__': # # Process(target=task,kwargs={'x':'子进程'}) # p=Process(tar

菜鸟随笔(3)---三种进程学习.孤儿进程.僵尸进程.守护进程

一只菜鸟横空出世,码农世界闯一闯,每天进展多一丢丢. 三种进程学习.孤儿进程.僵尸进程.守护进程 转自https://blog.csdn.net/believe_s/article/details/77040494 1.孤儿进程 如果父进程先退出,子进程还没退出那么子进程将被 托孤给init进程,这里子进程的父进程就是init进程(1号进程).其实还是很好理解的. // 父进程先子进程退出 // 子进程会被祖父进程接手并在后台运行,执行内部的代码 int main() { pid_t pid =

开启进程 守护进程

一:开启进程的方式 第一种 from multiprocessing import Process import time def task(name): print(f"{name} is running ") time.sleep(3) print(f"{name} is gone") if __name__ == '__main__': p = Process(target = task,args = ('常鑫',)) p.start() print('===

并发编程 之 进程 之 进程的模型: 进程同步的工具 (三) 继 创建进程( 守护进程)

multiProcessing 包中 Process模块: join() 堵塞问题, 可以理解为:  相当于 每个子进程结束时都会给 父进程发一条消息, join() 则是接收,内部有socket的实现 1, 进程之间的数据隔离问题 进程和进程之间的数据是隔离的, 内存空间不能共享,所以要想进行通信, 必须借助其他方法. 且这两个进程都是自愿的. 父子进程之间通过socket 通信. 2, 守护进程: daemon = True 守护进程的属性, 默认是 False 如果 设置成True 就表示

守护进程(setsid、getpgrp、setpgid、getpgid)以及系统日志(openlog、syslog、closelog)

守护进程:精灵进程 守护进程(Daemon)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件. 特点: 1.脱离控制终端 2.会话的leader 3.进程组的leader ============================= 系统日志: [root]# cd /var/log/    系统日志 主日志文件:messages syslogd服务----权限分离:每个用户将要提交的日志提交给syslogd服务,syslogd将日志写入系统日志 #in

Linux守护进程实现程序只运行一次

1.守护进程 守护进程(Daemon)是一种运行在后台的特殊进程,它独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件. 2.让程序只运行一次 如果让程序只运行一次,有很多方法,此处的一种方法是创建一个名字古怪的文件(保证不跟系统文件或其他文件重名),判断文件存在则让程序不再运行且提示程序正在运行,如果不存在则可以运行. 3.测试代码 此代码额外添加了系统LOG,记录操作的信息. 1 #include <stdio.h> 2 #include <unistd.h> 3

Linux系统开发7 进程关系,守护进程

[本文谢绝转载原文来自http://990487026.blog.51cto.com] <大纲> Linux系统开发7  进程关系守护进程 终端 网络终端 Linux PCB结构体信息 进程组 修改子进程.父进程的组ID 会话组 设置一个会话脱离控制终端 生成一个新的会话 守护进程 守护进程模板 获取当前系统时间  终端 在UNIX系统中用户通过终端登录系统后得到一个Shell进程这个终端成为Shell进 程的控制终端Controlling Terminal在讲进程时讲过控制终端是保存在PCB

linux中的守护进程

//一.守护进程 守护进程,也叫精灵进程(daemon) 它和普通后台进程的区别在于以下三点 1.守护进程自成会话,而普通后台进程则不一定 2.守护进程不受终端的控制 3.守护进程就是后台进程,而后台进程不同于守护进程 用ps axj命令查看系统中的进程,TPGID一栏为 -1 的进程(这些进程没有控制终端)就是守护进程. //二.实现 创建守护进程的步骤如下: 1.调用umask把[文件模式创建屏蔽字] 设置为 0 由于 umask 接收的参数会被取反,所以这个 0 传进去取反以后是最大的,也

.NET跨平台实践:用C#开发Linux守护进程

Linux守护进程(Daemon)是Linux的后台服务进程,它脱离了与控制终端的关联,直接由Linux init进程管理其生命周期,即使你关闭了控制台,daemon也能在后台正常工作. 一句话,为Linux开发与控制台无关的,需要在后台长时间不间断运行的“服务程序”,Daemon技术是非常重要的. Daemon程序一般用c/c++开发.不过,我今天要讲的,不是怎么用c/c++开发daemon,而是用C#! 一,创建Daemon程序: 用VS新建一个控制台项目,假设名称是MyDaemon,输入下

守护进程设计

课程索引 什么是守护进程 守护进程, 也就是通常说的Daemon( 精灵) 进程,是Linux中的一种服务进程. 它的特点是:•不占用控制终端(后台 运行)•独立于控制终端•独立于控制终端•周期性运行例如: smb 设计要素 2. 1 后台运行 守护进程需要独立于任何一个控制终端.实现方法调用是通过创建子进程来充当守护进程,而父进程退出,这样子进程就可以在后台运行.(范例展示)pid=fork();if(pid>0)if(pid>0)exit(0); //父进程退出else (pid==0){