Linux学习记录十四----------线程的创建和回收

文章目录

  • 五、Linux线程
      • 1.守护进程
        • 1.1.守护进程的特点
        • 1.2.进程组
        • 1.3会话
        • 1.4创建守护进程模型
      • 2.线程的概念
      • 3.线程的创建及相关函数
        • 3.1.创建线程‐‐pthread_create
        • 3.2.单个线程退出 --pthread_exit
        • 3.3.阻塞等待线程退出,获取线程退出状态--pthread_join
        • 3.4.线程分离函数--pthread_detach
        • 3.5.杀死(取消)线程--pthread_cancel
        • 3.6.比较两个线程ID是否相等(预留函数) --pthread_equal
      • 4.线程的分离属性


五、Linux线程

1.守护进程

守护进程是一种长期运行的进程(守护进程的生存期不一定长,但一般应该这样做),一般是操作系统启动的时候它就启动,操作系统关闭的时候它才关闭。守护进程跟终端无关联,也就是说它们没有控制终端,所以控制终端退出,也不会导致守护进程退出。守护进程是在后台运行的,不会占着终端,终端可以执行其他命令。Linux 操作系统本身是有很多的守护进程在默默地运行,维持着系统的日常活动。

1.1.守护进程的特点
  • 后台服务进程

  • 独立于控制终端

  • 周期性执行某任务

  • 不受用户登录注销影响

  • 一般采用以d结尾的名字(服务)

1.2.进程组
  • 进程的组长
    • 组里边的第一进程
    • 进程组的ID==进程中的组长的ID
  • 进程中组长的选择
    • 进程中的第一个进程
  • 进程组ID的设定
    • 进程组的ID就是组长的进程ID
1.3会话
  • 创建一个会话注意事项

    • 不能是进程组长
    • 创建会话的进程成为新进程组的组长
    • 有些lInux版本需要root权限执行此操作
    • 创建出的新会话会丢弃原有的控制终端 一般步骤;fork ,父亲死,儿子执行创建会话操作(setsid)
  • 获取进程所属的会话ID

    • pid_t getsid(pid_t pid);
  • 创建一个会话

    • pid_t setsid(void);
1.4创建守护进程模型
  • fork子进程,父进程退出 ----必须

  • 子进程创建新会话 -------必须

  • 改变当前工作目录chdir —非必须

  • 重设文件掩码 --非必须

  • 关闭文件描述符 --非必须

  • 执行核心工作----必须

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>int main()
{pid_t pid;pid = fork();if(pid == 0){pid_t sid;sid = setsid();//创建会话while(1){//执行核心工作sleep(1);}}else if(pid > 0){exit(0);//父进程退出}return 0;
}

在这里插入图片描述

2.线程的概念

在Linux下: 线程就是进程-轻量级进程 对于内核来货,线程就是进程 多进程和多线程的区别:

多进程: 始终共享的资源 代码、文件描述符、内存映射区–mmap

多线程:始终共享的资源:堆、全局变量,节省资源

  • 主线程和子线程

    • 共享: .text .bss .data 堆 动态加载区 环境变量 命令行参数
  • 通信:全局变量,堆

  • 不共享栈

    • eg一共五个线程,栈区被平均分成五块

在这里插入图片描述

  • 查看指定线程的LWP号:

    • 线程号和线程ID是有区别的
      • 线程号是给内核看的
  • 查看方式

    • 找到程序的进程ID

      • ps -Lf pid
      • top -p tid(线程状态动态显示)
        在这里插入图片描述

3.线程的创建及相关函数

3.1.创建线程‐‐pthread_create
int pthread_create( pthread_t *thread), //线程ID = 无符号长整型const pthread_attr_t *attr, //线程属性,NULLvoid *(*start_routine)(void *), //线程处理函数void *arg); //线程处理函数
/*@param:*		pthread:传出参数,线程创建成功之后,会被设置一个合适的值*		attr:默认传NULL*		start_routine:子线程的处理函数*		arg: 回调函数的参数*@return:成功:0,错误:错误号 //perror不能使用该函数打印错误信息*/
注意:主线程先退出,子线程会被强制结束验证线程直接共享全局变量

创建线程

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>int i = 0;void * pthread_son(void *arg)
{printf("create pthread successed pthid is %ld\n",pthread_self());while(i++){printf("i = %d\n",i);sleep(1);}}int main()
{pthread_t pthid;int ret;ret = pthread_create(&pthid,NULL,pthread_son,NULL);if(ret != 0){printf("error num is %d\n",ret);printf("%s\n",strerror(ret));return -1;}printf("create pthread successed parent pthid is %ld\n",pthread_self());for(;i < 5;i++){printf("i = %d\n",i);}sleep(3);return 0;
}

在这里插入图片描述

3.2.单个线程退出 --pthread_exit

不论是主线程还是子线程调用exit(0)后整个所以线程都会结束,而调用pthread_exit()只会退出当前进程

函数原型: void pthread‐exit(void *retval);
retval指针:必须指向全局,堆
3.3.阻塞等待线程退出,获取线程退出状态–pthread_join
函数原型:
int pthread_join(pthread_t pthread, void **retval)
/*参数:*		pthread:要回收的子线程的ID*		retval:读取线程退出的携带信息*	传出参数*		void* ptr;*/pthread_join(pthid,&ptr);指向的内存和pthread_exit参数指向地址一致

单个线程退出并回收

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>int i = 0;
int num = 100;
void * pthread_son(void *arg)
{printf("create pthread successed pthid is %ld\n",pthread_self());while(i++){printf("i = %d\n",i);sleep(1);if(i == 10){printf("exit pthread_son\n");pthread_exit(&num);//退出子线程}}}int main()
{pthread_t pthid;int ret;ret = pthread_create(&pthid,NULL,pthread_son,NULL);if(ret != 0){printf("error num is %d\n",ret);printf("%s\n",strerror(ret));return -1;}printf("create pthread successed parent pthid is %ld\n",pthread_self());for(;i < 5;i++){printf("i = %d\n",i);}void *ptr;pthread_join(pthid,&ptr);//回收线程ID为pthid的子线程printf("join child pthread  num is %d\n",*(int *)ptr);return 0;
}

在这里插入图片描述

3.4.线程分离函数–pthread_detach
函数原型:int pthread_datach(pthread_t thread);
调用该函数之后不需要 pthread_join
子线程会自动回收自己的PCB
3.5.杀死(取消)线程–pthread_cancel
函数原型: int pthread_cancel(pthread_t pthread);

pthread_testcancel();设置取消点—在取消点时就会杀死该线程

注:

  • 使用注意事项:

    • 在要杀死的子线程对应的处理的函数的内部,必须做过一次系统调用 (阻塞调用)
    • write read printf
    • int a = 2; int b = a+3;
    • 否则需要手动设置取消点
    int pthread_setcanceltype(int type,int *oldtype)
    PTHREAD_CANCEL_DEFERRED//等待目标点才会取消
    PTHREAD——CANCEL_ASYNCHRONOUS//目标线程会立即取消
    
3.6.比较两个线程ID是否相等(预留函数) --pthread_equal
函数原型:
int pthread_equal(pthread_t t1,pthread_t t2);

4.线程的分离属性

如果不回收线程资源会造成内存泄漏,且join不能完全回收线程资源

通过属性设置线程的分离

1.线程属性类型: pthread_attr_t attr;

2.线程属性操作函数:

  • 对线程属性变量的初始化
    • int pthread_attr_init(pthread_attr_t* attr);
  • 设置线程分离属性
    • int pthread_attr_setdetachstate( pthread_attr_t* attr, int detachstate );
    • 参数:
      • attr : 线程属性
      • detachstate PTHREAD_CREATE_DETACHED(分离) PTHREAD_CREATE_JOINABLE(非分离)
  • 释放线程资源函数 int pthread_attr_destroy(pthread_attr_t* attr);

设置分离属性

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h> 
#include <string.h>int i = 0;
int num = 100;
void * pthread_son(void *arg)
{printf("create pthread successed pthid is %ld\n",pthread_self());while(i++){printf("i = %d\n",i);sleep(1);if(i == 10){printf("exit pthread_son\n");pthread_exit(&num);}}}int main()
{pthread_t pthid;int ret;pthread_attr_t attr;pthread_attr_init(&attr);//初始化线程属性变量pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);//设置线程属性ret = pthread_create(&pthid,&attr,pthread_son,NULL);if(ret != 0){printf("error num is %d\n",ret);printf("%s\n",strerror(ret));return -1;}printf("create pthread successed parent pthid is %ld\n",pthread_self());for(;i < 5;i++){printf("i = %d\n",i);}sleep(15);pthread_attr_destroy(&attr);//释放线程资源函数return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/143059.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

无限制使用OpenAI最新o1-mini、o1-preview模型:经济高效的AI推理模型

OpenAI 最新推出的 o1 模型是该公司推理模型家族的首位成员&#xff0c;它通过创新的“思维链”训练模式&#xff0c;显著提升了逻辑推理和问题解决的能力。o1 模型在编程竞赛问题、数学奥林匹克资格赛以及物理、生物和化学问题的基准测试中表现出色&#xff0c;甚至在某些领域…

学成在线练习(HTML+CSS)

准备工作 项目目录 内部包含当前网站的所有素材&#xff0c;包含 HTML、CSS、图片、JavaScript等等 1.由于元素具有一些默认样式&#xff0c;可能是我们写网页过程中根本不需要的&#xff0c;所有我们可以在写代码之前就将其清除 base.css /* 基础公共样式&#xff1a;清除…

Tongweb7启动的时候显示要输入java参数(by lqw)

问题描述&#xff1a; 启动tongweb7的时候&#xff0c;提示要输入java参数&#xff0c;如下图所示&#xff1a; 原因&#xff1a; tongweb安装目录bin目录下的external.vmoptions文件改动&#xff0c;在# 符号后加多了一个空格。 external.vmoptions记录的是启动参数&#xf…

【读书】原则

后面的 太长了&#xff0c;而且太多了 我看作者 49年的 0多岁的老人的谆谆教诲 太多了 一下子吃不消 分为 生活原则 和 工作原则 倡导 人要以 原则而活 要做到极度透明 极度求真和极度透明&#xff1a;在软件开发中&#xff0c;对事实的执着追求和对信息的透明度是至关重要的。…

论文阅读 - SELF-REFINE: Iterative Refinement with Self-Feedback

https://arxiv.org/pdf/2303.17651 目录 Abstract Introduction 2 Iterative Refinement with SELF-REFINE Evaluation 3.1 Instantiating SELF-REFINE 3.2 Metrics 3.3 Results Abstract 与人类一样&#xff0c;大型语言模型&#xff08;LLMs&#xff09;并非总能在首次…

【刷题日记】螺旋矩阵

54. 螺旋矩阵 这个是一道模拟题&#xff0c;但我记得我大一第一次做这道题的时候真的就是纯按步骤模拟&#xff0c;没有对代码就行优化&#xff0c;导致代码写的很臃肿。 有这么几个地方可以改进。 看题目可以知道最终的结果一定是rows*cols个结点,所以只需要遍历rows*cols次…

java十进制码、六进制码和字符码的转换

一、字符转换为ASCII码&#xff1a; int i(int)1; 二、ASCII码转换为字符&#xff1a; char ch (char)40; 三、十六进制码转换为字符&#xff1a; char charValue (char)\u0040; package week3;public class check_point4_8 {public static void main(String[] args) {S…

Java 性能调优:优化 GC 线程设置

垃圾回收器使用一组称为 GC 线程的线程来执行回收工作。有时 JVM 可能会分配过多或过少的 GC 线程。本文将讨论 JVM 为什么会出现这种情况、其影响以及可能的解决方案。 1 咋查找应用程序的 GC 线程数量 进行线程转储分析来确定应用程序的 GC 线程数量&#xff1a; 从生产服…

【算法思想·二叉搜索树】基操篇

本文参考labuladong算法笔记[二叉搜索树心法&#xff08;基操篇&#xff09; | labuladong 的算法笔记] 1、概述 我们前文 东哥带你刷二叉搜索树&#xff08;特性篇&#xff09; 介绍了 BST 的基本特性&#xff0c;还利用二叉搜索树「中序遍历有序」的特性来解决了几道题目&am…

MathType7.9绿色和谐版激活补丁包下载

MathType7.9中文版&#xff1a;让你的数学公式更酷炫✨ 嘿&#xff0c;亲爱的数学迷们&#xff01;今天我要给你们安利一款超级炫酷的数学公式编辑器——MathType7.9中文版。这款软件不仅能让你轻松输入各种复杂的数学公式&#xff0c;还能让你的公式看起来更加酷炫哦&#xf…

Java项目——苍穹外卖(二)

Redis 简介 Redis是一个基于内存的key-value结构数据库 基于内存存储&#xff0c;读写性能高适合存储热点数据&#xff08;热点商品、资讯、新闻&#xff09;企业应用广泛 基础操作 启动 在redis安装目录中打开cmd&#xff0c;输入如上图指令即可启动&#xff0c;按下crtl…

【嘉立创EDA】画PCB板中为什么要两面铺铜为GND,不能一面GND一面VCC吗?

在新手画板子铺铜时&#xff0c;经常会铺一面GND一面VCC。但一般情况下我们不会这样铺铜。下面将详细分析为什么要两面铺铜为GND&#xff0c;而不是一面GND一面VCC的原因&#xff1a; 提高散热能力 金属导热性&#xff1a;金属具有良好的导热性&#xff0c;铺铜可以有效分散PCB…

unity的学习

因为需要构建一个三维物理环境,所以学习了unity,半天就可以,非常简单清晰 1.安装 去官网下载unity hub . 然后需要下载editor,但注意已经有了vs2022就不要再下一次了,下的时候会全放c盘,再安装.c盘都装不下了. 如果美游vs2022,就先自己把vs2022安装好,再安装unity hub.(其实不…

基于YOLOv5的农作物叶片病害识别系统

植物农作物叶片病虫害识别系统&#xff1a;农作物叶片病害AI检测与识别系统 源码 带UI界面说明视频 模型&#xff1a;yolov5 功能: 农作物叶片病害检测系统用于智能检测常见农作物叶片病害情况&#xff0c;自动化标注、记录和保存病害位置和类型&#xff0c;辅助作物病害防治以…

MyBatis XML映射文件编写【后端 18】

MyBatis XML映射文件编写 MyBatis 是一个优秀的持久层框架&#xff0c;它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解用于配置和原始映射&#xff0c;将接口和 Java 的 POJOs …

红帽7—Mysql的源码编译

到官网选择源码进行安装 使用wget命令下载链接 下载安装后对文件包进行解压 [rootnginx ~]# tar zxf mysql-boost-5.7.44.tar.gz 安装cmake编译工具 [rootnginx ~]# yum install cmake 使用源码编译安装mysql [rootmysql-node10 mysql-5.7.44]# cmake \ -DCMAKE_INSTALL_PRE…

6个Python小游戏项目源码【免费】

6个Python小游戏项目源码 源码下载地址&#xff1a; 6个Python小游戏项目源码 提取码: bfh3

Stable diffusion 学习过程

diffusion model 讲解&#xff1a; 【较真系列】讲人话-Diffusion Model全解(原理代码公式)_哔哩哔哩_bilibili stable diffusion【CVPR2022】 原始论文&#xff1a; https://arxiv.org/pdf/2112.10752 讲解&#xff1a;【论文简介】Stable Diffusion的基础论文:2112.High…

JZ2440开发板——S3C2440的UART的使用

以下内容源于韦东山课程的学习与整理&#xff0c;如有侵权请告知删除。 一、UART硬件简介 UART&#xff0c;全称是“Universal Asynchronous Receiver Transmitter”&#xff0c;即“通用异步收发器”&#xff0c;也就是我们日常说的“串口”。 它在嵌入式中用途非常广泛&…

牛客周赛 Round 60(下)

构造序列 题目描述 登录—专业IT笔试面试备考平台_牛客网 运行代码 #include <iostream> #include<stdio.h> #include<math.h> using namespace std; int main() {int n, m;cin >> n >> m;int minVal min(n, m);int maxVal max(n, m);cout …