首页 > 系统相关 >进程、线程和进程间的通信

进程、线程和进程间的通信

时间:2024-04-02 21:29:24浏览次数:12  
标签:int void 通信 线程 pthread 进程 include

技术笔记!

前言

一、概念

1.程序:存放在磁盘上的指令和数据的有序集合(文件),静态的

2.进程:执行一个程序所分配的资源的总称;进程是程序的一次执行过程

                动态的,包括创建、调度、执行和消亡;

3.进程和程序内容区别:

BSS段:通常是指用来存放程序中初始化的全局变量的一块内存区域。BSS是英文Block Started by Symbol的简称。

数据段:通常是指用来存放程序中初始化的全局变量的一块内存区域

代码段:通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。

堆(heap):堆是用于存放进程运行中被动态分配的内存段,当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)。 栈(stack):栈又称堆栈, 是用户存放程序临时创建的局部变量,(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进后出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。 4.进程的类型: 5. 进程状态

6. 进程状态图

二、进程

1.查看进程信息

(1)ps        查看系统进程快照

参数:

-e:显示所有进程;

-l:长格式显示更加详细的信息;

-f:全部列出,通常和其他选项;       

(2)top        查看进程动态信息

    shift + >        后翻页

    shift + <        前翻页

     top -p PID    查看某个进程

(3)/proc        查看进程详细信息

2.前后台进程切换

(1)jobs        查看后台进程;

(2)bg        将挂起的进程后台运行;

(3)fg        把后台运行的进程放到前台运行

3.改变进程优先级

(1)nice        按用户指定的优先级运行进程

(2)renice        该变正在运行进程的优先级

ctrl + z        把运行的前台进程转为后台并停止。

./test  &       把test程序后台运行。

4.进程的创建与结束

(1)子进程:由另外一个进程(对应称之为父进程)所创建的进程。
(2)子进程的创建         fork

函数:

#include  <unistd.h>

pid_t fork(void);

返回值:创建新的进程,失败返回-1;成功时父进程返回子进程的进程号,子进程返回0;

                通过fork的返回值区分父进程和子进程。

eg:

注意事项:

        (1)子进程只执行fork之后的代码;

        (2)父子进程执行顺序由操作系统决定的。

子进程继承了父进程的内容;

父子进程有独立的地址空间,互不影响

若父进程先结束

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

 子进程变成后台进程

若子进程先结束

 父进程如果没有及时回收,子进程变成僵尸进程

(2)进程结束        exit

函数:

        #include <stdlib.h>

        #include <unistd.h>

        void exit(int status);

        void _exit(int status);

        void _Exit(int status);

结束当前的进程并将status返回

exit结束进程时会刷新(流)缓冲区

eg:

return 和exit的区别

main函数结束时会隐式地调用exit函数,普通函数return是返回上一级。

5.进程回收        wait

(1)wait

#Include <sys/wait.h>

pid_t wait(int * status);

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

若子进程没有结束,父进程一直堵塞;若有多个子进程,那个子进程先结束就先回收;

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

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

eg:

   int status;

  pid_t pid;



  if ((pid = fork()) < 0) {

     perror(“fork”);  exit(-1);

  }

  else if (pid == 0) {

     sleep(1);  exit(2);

  }

  else {

     wait(&status);  printf(“%x\n”, status)

}

进程返回值和结束方式:

(2)  waitpid

函数:

#include <sys/wait.h>

pid_t waitpid(pid_t pid ,int* status, int option);

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

参数:

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

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

option 指定收回方式,0或WNOHANG(不管回收的进程是否结束都回收);

eg:

6.exec函数族

        进程调用exec函数族执行某个程序;进程当前内容被指定的程序替换;实现让父子进程执行不同的程序。

(1)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中查找

eg:

(2)execv /execvp

和execl函数的区别在于将参数封装成指针数组

函数:

#include  <unistd.h>

int execv(const char *path, char *const argv[]);

int execvp(const char *file, char *const argv[]);

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

参数:arg...封装成指针数组的形式。

eg:

(3)system

函数:

#include <stdlib.h>

int system(const char* command);

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

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

注意事项:

两个函数区别execlp不需要写文件名全路径,在PATH查找

 最后一个参数必须用空指针(NULL)作结束

进程当前内容被指定的程序替换,但进程号不变

第0个参数必须要写,虽然它没有使用

7.守护进程(Deamon Process)

守护进程:守护进程又叫精灵进程(Daemon Process),它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。

特点:

始终在后台运行,独立于任何终端,周期性的执行某种任务或等待处理特定事件。它是个特殊的孤儿进程,这种进程脱离终端,为什么要脱离终端呢?之所以脱离于终端是为了避免进程被任何终端所产生的信息所打断,其在执行过程中的信息也不在任何终端上显示。由于在 Linux 中,每一个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都会依附于这个终端,这个终端就称为这些进程的控制终端,当控制终端被关闭时,相应的进程都会自动关闭。

守护进程创建:
(1)创建子进程,父进程退出:

if (fork() > 0){

exit(0);

}

子进程变成孤儿进程,被init进程收养;子进程在后台运行。

(2)子进程创建新会话:setsid()

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< 3;i++){

close(i);

}

关闭所有从父进程继承的打开文件;已脱离终端,stdin/stdout/stderr无法再使用。

eg:

创建守护进程,每隔1秒将系统时间写入文件time.log 。

8.GDB调试多进程程序

set follow-fork-mode child        设置GDB调试子进程

set follow-fork-mode parent        设置GDB调试父进程

set detach-on-fork   on/off           设置GDB跟踪调试单个进程或多个

on: 只调试父进程或子进程的其中一个,(根据follow-fork-mode来决定),这是默认的模式

off:父子进程都在gdb的控制之下,其中一个进程正常调试(根据follow-fork-mode来决定),另一个进程会被设置为暂停状态。

info inferiord        显示GDB调试的进程

inferiors        进程序号(1,2,3.....)   切换GDB调试的进程

三、线程

线程查看命令:ps -eLf
1.进程和线程的区别

2.线程的特点

3.线程共享资源

vc

4.线程私有资源

5.linux线程库

使用pthread线程库,在编译时得链接pthread动态库(-lthread);

6.线程创建       pthread_create

返回值:成功时返回0,失败时返回错误码

参数:

thread        线程对象

attr        线程属性,NULL代表默认属性

routine        线程执行的函数

arg        传递给routine的参数,参数是void*,注意传递参数格式。

注意事项:

(1)主进程的退出,它创建的线程也会退出。

(2)线程创建需要时间,如果主进程马上退出,那线程不能得到执行。

7.线程结束        pthread_exit

结束当前进程;retval可被其他进程通过pthread_join获取;线程私有资源被释放。

8.线程查看tid函数

9.线程间参数传递

10.线程回收        pthread_join

对于一个默认属性的线程A来说,线程占用的资源并不会因为执行结束而得到释放,得调用pthread_join函数释放。

返回值:成功时返回0,失败时返回错误码;

thread要收回的线程对象;调用线程阻塞直到thread结束;*retval接收线程trhread的返回值。

11.线程分离        pthread_detach

作用是在线程结束后自动释放线程所占用的系统资源,无需等待主线程回收。

(1)int pthread_detach(pthread_t thread):

成功时返回0;失败返回错误码。

——指定该状态,线程主动于主控线程断开关系。线程结束后(不会产生僵尸线程)。

(2)pthread_attr_t attr;                //通过线程属性来设置游离态(分离态)

eg:

12.线程的取消        pthread_cancel

作用:随时杀死一个线程

int pthread_cancel(pthread_t thread);

注意:线程的取消要有取消点才可以,不是说取消就取消,线程的取消点主要是阻塞的系统调用。

如果没有取消点,可以手动设置一个:void pthread_testcancel(void);

设置取消使用或禁止使用:

int pthread_setcancelstate(int state, int *oldstate);

state的参数:

PTHREAD_CANCEL_ENABLE(enable  可以使用)

PTHREAD_CANCEL_DISABLE(disable 不能使用)

设置取消类型:

int pthread_setcanceltype(int type,int* outtype);

PTHREAD_CANCEL_DEFERRED                等到取消点才取消

PTHREAD_CANCEL_ASYNCHRONOUS           目标线程会立即取消

eg:

13.线程的清理        pthread_cleanup_xx

作用:当线程正常终止,需要清理一些资源。

void pthread_cleanup_push(void(*routine) (void*),void *arg)

void pthread_cleanup_pop(int execute);

成对使用

标签:int,void,通信,线程,pthread,进程,include
From: https://blog.csdn.net/weixin_52706451/article/details/136952998

相关文章

  • Csharp线程
    CSharpe线程目录CSharpe线程C#如何操作线程Thread1.Thread如何开启一个线程呢?2.Thread中常见的API3.thread的扩展封装threadpool一、.NETFramework2.0时代:出现了一个线程池ThreadPool二、线程池如何申请一个线程呢?三、线程等待四、线程池如何控制线程数量Task一、Task开启线......
  • 线程间通信之wait和notify
    synchronized解释:java语言的一个关键字作用:实现同步机制,控制多线程的访问,确保同一时刻只有一个线程可以进入临界区执行同步代码。用法:加在代码块上、加在方法上、加在一个对象,原理:不管是那种用法,都会有一个对象(指定的对象、class的实例对象、class对象),这个对象又会一一对应一......
  • 多线程的案例
    目录1.单例模式1.1饿汉模式1.2懒汉模式-单线程版1.3懒汉模式-多线程版1.3懒汉模式-多线程版(改进)2.阻塞队列2.1阻塞队列是什么2.2生产者消费模型2.3标准库中的阻塞队列2.4阻塞队列实现3.定时器3.1定时器是什么3.2标准库中的定时器3.3实现定时器4.线程池4.1线......
  • 进程的操作与管理(PV方法/死锁/存储方法)
     操作系统本质上是人机之间交互的接口,人通过操作系统(比如命令行、窗口、菜单)去操控计算机硬件;同时也是应用软件与硬件之间的接口(换而言之可以控制程序的运行)。操作系统的五大作用:进程管理、存储管理、文件管理、作业管理、设备管理上图就是典型的计算机结构:硬件层......
  • 【Frida】【Android】08_爬虫之网络通信库okhttp3
    ......
  • 【跳频通信】基于Gold码序列跳频通信附Matlab代码
     ✅作者简介:热爱科研的Matlab仿真开发者,修心和技术同步精进,代码获取、论文复现及科研仿真合作可私信。......
  • Worker 进行多线程任务开发
    概念介绍在OpenHarmony中,UI线程负责处理UI事件和用户交互,而Worker线程用于处理耗时操作,以提高应用程序的响应速度和用户体验。Worker线程是与主线程并行的独立线程,通常用于执行后台任务。需要注意的是,Worker线程中不能直接修改UI元素,UI更新必须在UI线程中进......
  • 常见的通信干扰及其时频图
    常见的通信干扰及其时频图单音干扰及其时频图多音干扰射频噪声干扰线性扫频干扰梳状干扰单音干扰及其时频图多音干扰射频噪声干扰线性扫频干扰梳状干扰......
  • 支持进程执行过程中途打断
    staticvoidMain(string[]args){Processprocess=null;CancellationTokenSourcecancellationTokenSource=null;do{varcommand=Console.ReadLine();if(command=="quit")break;if(comma......
  • Fiddler可以捕获和分析WebSocket通信
    自动化测试WebSocket接口使用Fiddler捕获WebSocket流量的步骤如下:其他WebSocket调试工具:用python的`websockets`库连接到ws接口:Fiddler可以捕获和分析WebSocket通信。Fiddler是一个功能强大的HTTP调试代理工具,广泛用于捕获HTTP和HTTPS网络流量。从它的较......