【从零开始的嵌入式生活】并发程序设计1——进程基本介绍(2)

简介: 【从零开始的嵌入式生活】并发程序设计1——进程基本介绍(2)

进程的回收

子进程结束时由父进程回收

孤儿进程由init进程回收

若没有及时回收会出现僵尸进程

进程回收 – wait

#include  <unistd.h>

pid_t wait(int *status);

#include  <unistd.h>
pid_t wait(int *status);


成功时返回回收的子进程的进程号;失败时返回EOF

若子进程没有结束,父进程一直阻塞

若有多个子进程,哪个先结束就先回收

status 指定保存子进程返回值和结束方式的地址

status为NULL表示直接释放子进程PCB,不接收返回值

相关示例在/study_qianrushi/5.proc/5.1base/wait.c

进程回收 – waitpid

#include  <unistd.h>
  pid_t waitpid(pid_t pid, int *status, int option);


成功时返回回收的子进程的pid或0;失败时返回EOF

pid可用于指定回收哪个子进程或任意子进程

status指定用于保存子进程返回值和结束方式的地址

option指定回收方式,0 或 WNOHANG

waitpid(pid, &status, 0);
waitpid(pid, &status, WNOHANG);
waitpid(-1, &status, 0);
waitpid(-1, &status, WNOHANG);


DXEC函数族

进程调用exec函数族执行某个程序

进程当前内容被指定的程序替换

实现让父子进程执行不同的程序


父进程创建子进程

子进程调用exec函数族

父进程不受影响

进程 – execl / execlp

#include  <unistd.h>
int execl(const char *path, const char *arg, …);
int execlp(const char *file, const char *arg, …);


成功时执行指定的程序;失败时返回EOF

path 执行的程序名称,包含路径

arg… 传递给执行的程序的参数列表

file 执行的程序的名称,在PATH中查找

#include <unistd.h>
#include <stdio.h>
int main(){
       if(execl("/bin/ls", "ls", "-a", "-l", "./", NULL) < 0){
               perror("execl");
       }
       printf("I ls current dircctory\n");
       return 0;
}


最后的一个参数一定是空!!!

execl之后的所有内容都会被替换掉,不会执行!!!!


进程 – execv / execvp

#include  <unistd.h>
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);


成功时执行指定的程序;失败时返回EOF

arg… 封装成指针数组的形式

与上面的程序类似,但是argv可以变化,更灵活一些,推荐使用。


system

#include  <stdlib.h>
int system(const char *command);


成功时返回命令command的返回值;失败时返回EOF

当前进程等待command执行结束后才继续执行


守护进程

守护进程(Daemon)是Linux三种进程类型之一

通常在系统启动时运行,系统关闭时结束

Linux系统中大量使用,很多服务程序以守护进程形式运行

特点:


始终在后台运行

独立于任何终端

周期性的执行某种任务或等待处理特定事件

Linux以会话(session)、进程组的方式管理进程

每个进程属于一个进程组

会话是一个或多个进程组的集合。通常用户打开一个终端时,系统会创建一个会话。所有通过该终端运行的进 程都属于这个会话

终端关闭时,所有相关进程会被结束


守护进程创建

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


if (fork() > 0)  {
       exit(0);
    }


子进程变成孤儿进程,被init进程收养

子进程在后台运行

2.子进程创建新会话


if (setsid() < 0)  {
exit(-1);
}


子进程成为新的会话组长

子进程脱离原先的终端

3.更改当前工作目录


chdir(“/”);
chdir(“/tmp”);


守护进程一直在后台运行,其工作目录不能被卸载

重新设定当前工作目录cwd

4.重设文件权限掩码


if (umask(0) < 0)  {
 exit(-1);
}


文件权限掩码设置为0

只影响当前进程

5.关闭打开的文件描述符


int  i;
for(i=0; i<getdtablesize(); i++) {
close(i);
}


关闭所有从父进程继承的打开文件

已脱离终端,stdin / stdout / stderr无法再使用

示例代码


#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
int main(){
        pid_t pid;
        //first step
        pid = fork();
        if(pid < 0){
                perror("fork");
                return -1;
        }else if(pid > 0){
                exit(0);
        }
        //second step
        pid = setsid();
        if(pid == -1){
                perror("setsod");
                return -1;
        }
        //third step
        chdir("/");
        umask(0);
        int i;
        for(i = 0;i < 2;++i){
                close(i);
        }
        FILE *fp;
        time_t ctm;
        fp = fopen("1.log", "w");
        while(1){
                ctm = time(NULL);
                fputs(ctime(&ctm), fp);
                fflush(fp);
                sleep(1);
        }
        return 0;
}


写在最后

今天开启并发编程,我尽量一天一更,大家和我一起变强呀!明天开始进入线程专题!最后三连即可提高学习效率!!!


另外我在更新的就是算法笔记的一些例题笔记,这个系列是用于提高我的算法能力,如果有兴趣对算法领域感兴趣找不到合适的入门文章也可以追更,如果我更新的太慢了请大家点赞收藏,一键三连才能更有更新的动力呀0.0


相关文章
|
4月前
|
安全 Python
告别低效编程!Python线程与进程并发技术详解,让你的代码飞起来!
【7月更文挑战第9天】Python并发编程提升效率:**理解并发与并行,线程借助`threading`模块处理IO密集型任务,受限于GIL;进程用`multiprocessing`实现并行,绕过GIL限制。示例展示线程和进程创建及同步。选择合适模型,注意线程安全,利用多核,优化性能,实现高效并发编程。
72 3
|
4月前
|
Python
解锁Python并发新世界:线程与进程的并行艺术,让你的应用性能翻倍!
【7月更文挑战第9天】并发编程**是同时执行多个任务的技术,提升程序效率。Python的**threading**模块支持多线程,适合IO密集型任务,但受GIL限制。**multiprocessing**模块允许多进程并行,绕过GIL,适用于CPU密集型任务。例如,计算平方和,多线程版本使用`threading`分割工作并同步结果;多进程版本利用`multiprocessing.Pool`分块计算再合并。正确选择能优化应用性能。
36 1
|
2月前
|
网络协议 C语言
C语言 网络编程(十三)并发的TCP服务端-以进程完成功能
这段代码实现了一个基于TCP协议的多进程并发服务端和客户端程序。服务端通过创建子进程来处理多个客户端连接,解决了粘包问题,并支持不定长数据传输。客户端则循环发送数据并接收服务端回传的信息,同样处理了粘包问题。程序通过自定义的数据长度前缀确保了数据的完整性和准确性。
|
3月前
|
算法 Java
JUC(1)线程和进程、并发和并行、线程的状态、lock锁、生产者和消费者问题
该博客文章综合介绍了Java并发编程的基础知识,包括线程与进程的区别、并发与并行的概念、线程的生命周期状态、`sleep`与`wait`方法的差异、`Lock`接口及其实现类与`synchronized`关键字的对比,以及生产者和消费者问题的解决方案和使用`Condition`对象替代`synchronized`关键字的方法。
JUC(1)线程和进程、并发和并行、线程的状态、lock锁、生产者和消费者问题
|
2月前
|
C语言
C语言 网络编程(八)并发的UDP服务端 以进程完成功能
这段代码展示了如何使用多进程处理 UDP 客户端和服务端通信。客户端通过发送登录请求与服务端建立连接,并与服务端新建的子进程进行数据交换。服务端则负责接收请求,验证登录信息,并创建子进程处理客户端的具体请求。子进程会创建一个新的套接字与客户端通信,实现数据收发功能。此方案有效利用了多进程的优势,提高了系统的并发处理能力。
|
2月前
|
数据采集 消息中间件 并行计算
进程、线程与协程:并发执行的三种重要概念与应用
进程、线程与协程:并发执行的三种重要概念与应用
57 0
|
3月前
|
存储 缓存 NoSQL
进程内缓存助你提高并发能力!
进程内缓存助你提高并发能力!
|
4月前
|
数据库 数据安全/隐私保护 C++
Python并发编程实战:线程(threading)VS进程(multiprocessing),谁才是并发之王?
【7月更文挑战第10天】Python并发对比:线程轻量级,适合I/O密集型任务,但受GIL限制;进程绕过GIL,擅CPU密集型,但通信成本高。选择取决于应用场景,线程利于数据共享,进程利于多核利用。并发无“王者”,灵活运用方为上策。
54 2
|
4月前
|
大数据 API 数据处理
Python高手都在用的并发秘籍:解锁线程与进程的终极奥义,性能飙升不是梦!
【7月更文挑战第8天】Python并发编程提升性能,线程(threading)适合I/O密集型任务,如网络请求,通过`start()`和`join()`实现并发。进程(multiprocessing)利用多核CPU,适用于CPU密集型任务,如大数据处理。结合两者可优化混合任务,实现最佳并发效果。
34 1
|
4月前
|
消息中间件 算法 Java
(十四)深入并发之线程、进程、纤程、协程、管程与死锁、活锁、锁饥饿详解
本文深入探讨了并发编程的关键概念和技术挑战。首先介绍了进程、线程、纤程、协程、管程等概念,强调了这些概念是如何随多核时代的到来而演变的,以满足高性能计算的需求。随后,文章详细解释了死锁、活锁与锁饥饿等问题,通过生动的例子帮助理解这些现象,并提供了预防和解决这些问题的方法。最后,通过一个具体的死锁示例代码展示了如何在实践中遇到并发问题,并提供了几种常用的工具和技术来诊断和解决这些问题。本文旨在为并发编程的实践者提供一个全面的理解框架,帮助他们在开发过程中更好地处理并发问题。

热门文章

最新文章