目录
前言
上篇博客对C/C++进程的上部分进行了详细讲解,本篇博客将继续讲解和补充关于线程的知识点。
一、守护进程
1.概念
2.守护进程创建的原理(如图清晰可见)
3.守护进程的实现(代码块)
void init_deamon(void)
{
/*************** start ****************************/
pid_t pid;
int i,max_fd;
//1,创建子进程
if((pid = fork()) < 0){
perror("fork");
exit(1);
}else if(pid > 0)
exit(0);
//2,创建新会话
if(setsid() < 0){
perror("setsid");
exit(1);
}
//3,再创建子进程
if((pid = fork()) < 0){
perror("fork");
exit(1);
}else if(pid > 0)
exit(0);
//4,修改守护进程的工作目录
chdir("/");
//5,关闭进程父进程的所有的文件描述符
max_fd = sysconf(_SC_OPEN_MAX);
for (i = 0; i < max_fd;i++)
close(i);
//6,将标准输入,标准输出和标准错误重定向到/dev/null
open("/dev/null",O_RDWR);
dup(0);
dup(0);
//7,消除umask影响
umask(0);
/*************** end ****************************/
}
二、dup和dup2
1,复制文件描述符
2.文件描述符重定向
三、系统日志
1,打开日志
2,向日志中写消息
3,关闭日志
四,文件锁
1.概念
2,给整个文件上锁
实例代码如下:
代码一:
int main(int argc,char **argv)
{
int fd;
int i;
if(argc != 2){
fprintf(stderr,"Usage: %s <filename>\n",argv[0]);
exit(0);
}
if((fd = open(argv[1],O_RDWR)) < 0){
perror("open");
exit(1);
}
while(1){
printf("等待获取锁\n");
//获取互斥锁
if(flock(fd,LOCK_EX) < 0){
perror("flock");
exit(1);
}
for(i = 0; i < 7; i++){
printf("正在上厕所\n");
sleep(1);
}
//释放锁
if(flock(fd,LOCK_UN) < 0){
perror("flock");
exit(1);
}
printf("上完厕所出来了....\n");
sleep(1);
}
return 0;
}
代码二:
int main(int argc,char **argv)
{
int fd;
int i;
if(argc != 2){
fprintf(stderr,"Usage: %s <filename>\n",argv[0]);
exit(0);
}
if((fd = open(argv[1],O_RDWR)) < 0){
perror("open");
exit(1);
}
while(1){
printf("等待着上厕所\n");
//获取互斥锁
if(flock(fd,LOCK_EX) < 0){
perror("flock");
exit(1);
}
for(i = 0; i < 7; i++){
printf("正在上厕所...\n");
sleep(1);
}
//释放锁
if(flock(fd,LOCK_UN) < 0){
perror("flock");
exit(1);
}
printf("上完厕所!\n");
sleep(1);
}
return 0;
}
3,给文件的某个区域上锁
实例代码如下:
//定义锁的结构体--设置锁的区域
struct flock fl = {
.l_whence = SEEK_SET,
.l_start = 100,
.l_len = 1024,
};
while(1){
printf("等待获取锁\n");
//获取互斥锁
fl.l_type = F_WRLCK; //设置锁的类型
if(fcntl(fd,F_SETLKW,&fl) < 0){
perror("flock");
exit(1);
}
for(i = 0; i < 7; i++){
printf("正在上厕所\n");
sleep(1);
}
//释放锁
fl.l_type = F_UNLCK; //解锁
if(fcntl(fd,F_SETLK,&fl) < 0){
perror("flock");
exit(1);
}
printf("上完厕所出来了....\n");
sleep(1);
}
五,进程间通信
1.分类
2,无名管道
2.1 无名管道通信原理
2.2 用法
实例代码如下:
int main(void)
{
int fd[2];
pid_t pid;
char buf[100];
//创建无名管道
if(pipe(fd) < 0){ //pipe()会在内核中创建无名管道,然后将管道两端的文件描述符返回给当前进程
perror("pipe");
exit(1);
}
//创建子进程
if((pid = fork()) < 0){
perror("fork");
exit(1);
}else if(!pid){ //子进程执行:从键盘获取字符串,写到管道中
close(fd[0]); //关闭读端
while(1){
fgets(buf,sizeof(buf),stdin);
write(fd[1],buf,strlen(buf)); //向管道中写数据
}
}else{ //父进程执行:从管道读数据,打印到屏幕上
close(fd[1]); //关闭写端
while(1){
if(read(fd[0],buf,sizeof(buf)) < 0){
perror("read");
exit(1);
}
printf("%s",buf);
}
}
return 0;
}
总结
本篇文章针对进程进行超详细讲解和补充,希望能够帮到大家!
以后还会给大家展现更多关于嵌入式和C语言的其他重要的基础知识,感谢大家支持懒大王!
希望这篇博客能给各位朋友们带来帮助,最后懒大王请来过的朋友们留下你们宝贵的三连以及关注,感谢你们!