【Linux】线程基本概念,线程控制

news2024/11/27 20:39:12

目录

基本概念

重新理解进程

线程真实存在吗?

问题解答

线程资源

线程控制

线程创建

如何全面看待线程函数传参

如何看到线程函数返回

线程查询

线程等待

线程终止

线程分离


基本概念

线程(thread)是指在单个进程内,多路并行执行的创建和管理单元;

重新理解进程

在没有学习线程的时候,我们学的进程=内核数据结构+程序的代码和数据;每个进程系统都会为其分配task_struct(PCB),mm_struct(虚拟地址空间),页表来描述和管理进程;

上面的整个才是进程,进程是程度系统资源分配的基本实体;

而线程其实就是进程内的执行流;和之前的进程对比,之前的进程就是内部只有一个执行流的进程!

线程真实存在吗?

在windows中存在真正的进程tcb,而在Linux中并不存在真正的进程,Linux中是用进程来模拟线程!!!

因为复原PCB,同PCB来统一表示执行流,这样的话就不需要为线程单独设计数据结构和调度算法了;像进程一样,线程在程序中有独立,并发的执行路径,每个线程都有它自己私有的栈空间,自己的程序计数器,自己的寄存器,但是他们共享全局数据区,文件描述符等;

问题解答

既然线程用PCB来模拟,那CPU会不会区分task_struct是线程还是进程呢

不做区分,CPU统一将他们看做执行流;Linux中执行流统一被称为轻量级进程;

那么,既然有了多进程,为什么要有多线程呢

  • 进程的创建成本高,创建线程的成本低
  • 线程调度成本低
  • 删除线程成本低

为什么说线程调度成本低呢?

主要原因是在进程切换时,由于线程共享进程的内存空间和资源,cpu的cache中数据往往有效,因此减少了因cache不命中导致的缺页中断开销。

既然线程这么好用,为什么要有进程呢?

虽然线程有很多优势,但也不是毫无代价的.事实上,有些最可怕的bug就是由多线程引起的.设计,编写,理解以及最重要的----调试多线程程序,这些复杂度都是远远高于单个线程的进程.                      最主要的原因:多个虚拟的处理器,但是只有一个虚拟化内存实例,当一个线程同步失败,就会使整个进程运行出错以及程序崩溃;

线程资源

线程共享资源:

  • 进程地址空间
  • 文件描述符表
  • 信号处理方式
  • 当前工作目录
  • 用户ID和组ID

线程私有资源:

  • 线程ID
  • 私有栈空间(重要)
  • 一组寄存器(重要)
  • 程序计数器
  • errno变量
  • 调度优先级
  • 信号屏蔽字

线程控制

线程创建

pthread_create:创建线程

#include <iostream>
#include <unistd.h>
#include<pthread.h>
using namespace std;

void *pthreadRun(void *args)
{
    while(true)
    {

        cout<<"I am "<<(const char *)args<<endl;
        sleep(1);
    }
    return nullptr;
}
int main()
{
    pthread_t tid;
    pthread_create(&tid,nullptr,pthreadRun,(void *)"thread-1");

    while(true)
    {
        cout<<"I am main thread"<<endl;
        sleep(1);
    }
    return 0;
}

运行结果:

如何全面看待线程函数传参

给线程传参可以是任意类型,也可以是类对象类型;

void* 指针可以指向任意类型的数据;

具体的void*内容可以看下面的文章:

c语言---指针(1)-CSDN博客

(1)

运行结果: 

(2)不推荐

 

运行结果: 

既然不推荐的话,怎么优化呢?

    ThreadData *td =new ThreadData();
    td->name="thread";
    td->num="1";
如何看到线程函数返回
  • 只考虑正确的返回,不考虑异常,因为异常了,整个进程就崩溃了,包括主线程
  • 可以传任意参数,也可以是任意类对象

运行结果:

线程查询

怎么查询线程有没有创建成功呢?

ps -aL:查询线程

ps ajx:查询进程

我们会发现同一个进程下创建的多线程的PID是一样的,但是每个线程的LWP是不一样的;其实OS调度时看到是LWP并不是PID,我们在没有学习线程的时候说的是PID,和现在的说法不是冲突了吗?其实并不是我们之前创建的不管是多进程还是单进程,在进程中都是只有一个执行流的,那是PID和LWP是相同的,所以我们之前所说的PID,其实看到还是LWP只不过LWP和PID一样;学完线程后,我们以后就要说LWP了;

怎么查询线程的LWP呢?

void *pthreadRun(void *args)
{
    cout<<"tid :"<<pthread_self()<<endl;
    while(true)
    {

        cout<<"I am "<<(const char *)args<<endl;
        sleep(1);
    }
    return nullptr;
}

运行结果: 

线程等待

我们期望主线程先退出还是新线程最后退出?   ---->  当然是主线程了,那如何保证main thread最后退出呢?

join来保证,这时就要用到pthread_join来等待新线程;

int main()
{
    pthread_t tid;
    int n=pthread_create(&tid,nullptr,pthreadRun,(void *)"thread-1");
    if(n!=0)
    {
        cout<<strerror(errno)<<endl;
        return 1;
    }

    //期望谁最后退出?主线程,还是新线程  -->main thread 如何保证?
    n = pthread_join(tid,nullptr);
    if(n==0)
    {
        cout<<"main thread wait sucess"<<endl;
    }

    return 0;
}

运行结果: 

 

线程终止

在进程的学习时,我们学过进程的终止有:

  • return
  • exit
  • 信号

那线程的终止有哪些呢?

1、自然退出:线程函数return

2、pthread_exit()                                                                                                                                    我们不能用exit()来进行线程的退出,如果一个线程退出时,用了exit,那么整个进程就会退出,因为exit是用来终止进程的;

3、pthread_cancel :取消一个线程                                                                                                        

线程分离

既然进程有SIGCHLD信号可以让进程不等待,那线程有没有类似的可以让线程也不等待?

当然有了,就是pthread_detach;

  1. 一个线程被创建默认是joinable的,必须被join
  2. 如果一个线程被分离,线程的工作状态处于分离状态,那么就不需要/不必要被join的,但是依旧属于进程内部,只是不需要等待了而已;分离不等于分家;                                            

以上就是线程的基本概念,线程控制的全部内容!!!

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

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

相关文章

探索前端与 AI 的结合:如何用 GPT-4 助力开发效率

前言&#xff1a;开发者的“神队友” GPT-4 还记得那些深夜奋战&#xff0c;紧盯着屏幕敲代码的日子吗&#xff1f;表单不验证、布局乱飞、BUG 根本找不到&#xff0c;这些时刻简直能让人抓狂。你可能会想&#xff1a;“要是有个智能助手能帮我搞定这些多好&#xff01;” 那么…

#HarmonyOS:页面和自定义组件生命周期

页面生命周期 即被Entry装饰的组件生命周期 onPageShow&#xff1a;页面每次显示时触发一次&#xff0c;包括路由过程、应用进入前台等场景。onPageHide: 页面每次隐藏时触发一次&#xff0c;包括路由过程、应用进入后台等场景。onBackPress: 当用户点击返回按钮是触发 组件…

全面了解 NGINX 的负载均衡算法

NGINX 提供多种负载均衡方法&#xff0c;以应对不同的流量分发需求。常用的算法包括&#xff1a;最少连接、最短时间、通用哈希、随机算法和 IP 哈希。这些负载均衡算法都通过独立指令来定义&#xff0c;每种算法都有其独特的应用场景。 以下负载均衡方法&#xff08;IP 哈希除…

如何让自己的网站,被更多的人搜索到(免费方案)

文章目录 一、要做时间的朋友二、需要独立IP的服务器三、SEO信息如何设置设置网站TDK生成网站地图设置搜索引擎自动提交部署SSL证书加分项&#xff1a;定期更新文章 引言&#xff1a; 许多人都有这样一个问题&#xff1a;做好自己的网站&#xff0c;如何让这个网站被更多的人浏…

WPF实现类似网易云音乐的菜单切换

这里是借助三方UI框架实现了&#xff0c;感兴趣的小伙伴可以看一下。 深色模式&#xff1a;​ 浅色模式&#xff1a; ​这里主要使用了以下三个包&#xff1a; MahApps.Metro&#xff1a;UI库&#xff0c;提供菜单导航和其它控件​​​​​​​ 实现步骤&#xff1a;1、使用B…

SSRF-利用dict协议-攻击redis

1.靶场准备&#xff1a; CTFHub-技能树-Web-SSRF-Redis协议 蚁剑AntSword 2.简述&#xff1a; 2.1 SSRF 服务器端请求伪造&#xff0c;存在一个url参数&#xff0c;一般用于图片上传、网页重定向等&#xff0c;我们可以控制url参数&#xff0c;去访问内网服务器的敏感内容…

前端vue框架配置基础信息详解分析

前端vue2、vue3框架是我们最近常用的框架&#xff0c;今天我们分析一下配置基础信息、详解其中的功能含义。 1、vue.config.js 文件分析 这个 vue.config.js 文件是 Vue CLI 项目中用于配置项目构建行为和开发环境设置的文件。它能够让开发者定制打包、代理、路径、样式等方面…

干货:落地企业级RAG的实践指南

1. 什么是RAG&#xff1f; 检索增强生成&#xff08;Retrieval-Augmented Generation&#xff0c;简称 RAG&#xff09;通过结合大型语言模型&#xff08;LLM&#xff09;和信息检索系统来提高生成文本的准确性和相关性.这种方法允许模型在生成回答之前&#xff0c;先从权威知…

spdlog学习记录

spdlog Loggers&#xff1a;是 Spdlog 最基本的组件&#xff0c;负责记录日志消息。在 Spdlog 中&#xff0c;一个 Logger 对象代表着一个日志记录器&#xff0c;应用程序可以使用 Logger 对象记录不同级别的日志消息Sinks&#xff1a;决定了日志消息的输出位置。在 Spdlog 中&…

深入拆解TomcatJetty(三)

深入拆解Tomcat&Jetty&#xff08;三&#xff09; 专栏地址&#xff1a;https://time.geekbang.org/column/intro/100027701 1 Tomcat组件生命周期 Tomcat如何如何实现一键式启停 Tomcat 架构图和请求处理流程如图所示&#xff1a; 对组件之间的关系进行分析&#xff0c;…

MySQL(python开发)——(3)表数据的基本操作,增删改查

MySQL&#xff08;python开发)——&#xff08;1&#xff09;数据库概述及其MySQL介绍 MySQL&#xff08;python开发)——&#xff08;2&#xff09;数据库基本操作及数据类型 MySQL—— 表数据基本操作 一、表中插入(insert)数据——增 insert into 表名 values (值1&#…

人工智能正在扼杀云计算的可持续性

可持续性曾是公共云计算中备受推崇的优势。企业和云提供商大肆宣扬他们的绿色计划&#xff0c;推广采用可再生能源的数据中心&#xff0c;以减少碳足迹。 近几个月来&#xff0c;这个话题已悄然淡出人们的视线。罪魁祸首是什么&#xff1f;对人工智能功能的无限需求正在推动云…

大数据-180 Elasticsearch - 原理剖析 索引写入与近实时搜索

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

Django配置路由后,为什么输入http://127.0.0.1:8000/ 网址后报错了?

问题探讨&#xff1a;为什么输入http://127.0.0.1:8000/ 网址后报错了&#xff1f; 翻译一下&#xff1a; 屏蔽一下新加的路由 发现界面正常了 现在翻译一下&#xff1a; 是不是比较理解了&#xff0c;admin 属于默认配置的URL,所以urlpatterns为空列表或仅配置admin路由时&…

【算法篇】贪心类(1)(笔记)

目录 一、理论基础 1. 大纲 2. 求解步骤 二、Leetcode 题目 1. 分发饼干 2. 摆动序列 3. 最大子序和 4. 买卖股票的最佳时机 II 5. 跳跃游戏 6. 跳跃游戏 II 7. K 次取反后最大化的数组和 8. 加油站 9. 分发糖果 一、理论基础 1. 大纲 2. 求解步骤 将问题分解为…

人工智能:塑造未来生活与工作的力量

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《热点时事》 期待您的关注 引言 随着人工智能技术的不断发展&#xff0c;我们已经看到了它在各行业带来的巨大变革。 在医疗行业中…

【wpf】08 xml文件的存取操作

在使用wpf编程过程中&#xff0c;会用到xml的配置文件&#xff0c;实现对其读取和存储的操作是必须的。 1 xml说明 可扩展标记语言 (Extensible Markup Language, XML) &#xff0c;标准通用标记语言的子集&#xff0c;可以用来标记数据、定义数据类型&#xff0c;是一种允许…

git clone报错fatal: pack has bad object at offset 186137397: inflate returned 1

逐步拷贝 https://stackoverflow.com/questions/27653116/git-fatal-pack-has-bad-object-at-offset-x-inflate-returned-5 https://www.cnblogs.com/Lenbrother/p/17726195.html https://cloud.tencent.com/developer/ask/sof/107092182 git clone --depth 1 <repository…

外包干了30年,人都快要废了。。。。。

先说一下自己的情况&#xff0c;本科生&#xff0c;19年通过校招进入南京某软件公司&#xff0c;干了接近2年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了2年的功能测试&…

如何做软件系统的维护成本估算?

一、人员成本 维护工程师 确定维护工程师的数量和技能级别。例如&#xff0c;可能需要 2 名中级维护工程师&#xff0c;月薪 10000 元左右。计算每月的人员成本为 2 10000 20000 元。 技术支持人员 技术支持人员负责解答用户的问题和处理紧急情况。假设需要 1 名技术支持人员…