array(2) { ["docs"]=> array(10) { [0]=> array(10) { ["id"]=> string(3) "428" ["text"]=> string(77) "Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(8) "DonetRen" ["tagsname"]=> string(55) "Visual Studio 2017|MSDN帮助|C#程序|.NET|Help Viewer" ["tagsid"]=> string(23) "[401,402,403,"300",404]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400964" ["_id"]=> string(3) "428" } [1]=> array(10) { ["id"]=> string(3) "427" ["text"]=> string(42) "npm -v;报错 cannot find module "wrapp"" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "zzty" ["tagsname"]=> string(50) "node.js|npm|cannot find module "wrapp“|node" ["tagsid"]=> string(19) "[398,"239",399,400]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400760" ["_id"]=> string(3) "427" } [2]=> array(10) { ["id"]=> string(3) "426" ["text"]=> string(54) "说说css中pt、px、em、rem都扮演了什么角色" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(12) "zhengqiaoyin" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511400640" ["_id"]=> string(3) "426" } [3]=> array(10) { ["id"]=> string(3) "425" ["text"]=> string(83) "深入学习JS执行--创建执行上下文(变量对象,作用域链,this)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "Ry-yuan" ["tagsname"]=> string(33) "Javascript|Javascript执行过程" ["tagsid"]=> string(13) "["169","191"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511399901" ["_id"]=> string(3) "425" } [4]=> array(10) { ["id"]=> string(3) "424" ["text"]=> string(30) "C# 排序技术研究与对比" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "vveiliang" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(8) ".Net Dev" ["catesid"]=> string(5) "[199]" ["createtime"]=> string(10) "1511399150" ["_id"]=> string(3) "424" } [5]=> array(10) { ["id"]=> string(3) "423" ["text"]=> string(72) "【算法】小白的算法笔记:快速排序算法的编码和优化" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(9) "penghuwan" ["tagsname"]=> string(6) "算法" ["tagsid"]=> string(7) "["344"]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511398109" ["_id"]=> string(3) "423" } [6]=> array(10) { ["id"]=> string(3) "422" ["text"]=> string(64) "JavaScript数据可视化编程学习(二)Flotr2,雷达图" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "chengxs" ["tagsname"]=> string(28) "数据可视化|前端学习" ["tagsid"]=> string(9) "[396,397]" ["catesname"]=> string(18) "前端基本知识" ["catesid"]=> string(5) "[198]" ["createtime"]=> string(10) "1511397800" ["_id"]=> string(3) "422" } [7]=> array(10) { ["id"]=> string(3) "421" ["text"]=> string(36) "C#表达式目录树(Expression)" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(4) "wwym" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(4) ".NET" ["catesid"]=> string(7) "["119"]" ["createtime"]=> string(10) "1511397474" ["_id"]=> string(3) "421" } [8]=> array(10) { ["id"]=> string(3) "420" ["text"]=> string(47) "数据结构 队列_队列实例:事件处理" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(7) "idreamo" ["tagsname"]=> string(40) "C语言|数据结构|队列|事件处理" ["tagsid"]=> string(23) "["246","247","248",395]" ["catesname"]=> string(12) "数据结构" ["catesid"]=> string(7) "["133"]" ["createtime"]=> string(10) "1511397279" ["_id"]=> string(3) "420" } [9]=> array(10) { ["id"]=> string(3) "419" ["text"]=> string(47) "久等了,博客园官方Android客户端发布" ["intro"]=> string(288) "目录 ECharts 异步加载 ECharts 数据可视化在过去几年中取得了巨大进展。开发人员对可视化产品的期望不再是简单的图表创建工具,而是在交互、性能、数据处理等方面有更高的要求。 chart.setOption({ color: [ " ["username"]=> string(3) "cmt" ["tagsname"]=> string(0) "" ["tagsid"]=> string(2) "[]" ["catesname"]=> string(0) "" ["catesid"]=> string(2) "[]" ["createtime"]=> string(10) "1511396549" ["_id"]=> string(3) "419" } } ["count"]=> int(200) } 222 数组,父子进程,守护进程 - 爱码网

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);
}
}

}


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

相关文章: