Linux(一)线程——何为线程???Linux线程控制

文章目录

  • 什么是线程???
  • 线程和进程的区别和联系
  • Linux线程控制
    • POSIX线程库
    • 创建线程
    • 线程等待
    • 线程终止
    • 线程分离

什么是线程???

  • 在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是“一个进程内部的控制序列”
  • 一切进程至少都有一个执行线程
  • 线程在进程内部运行,本质是在进程地址空间内运行
  • 在Linux系统中,在CPU眼中,看到的PCB都要比传统的进程更加轻量化
  • 透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流

在这里插入图片描述

每个进程都有自己独立的进程地址空间和独立的页表

如果我们在创建“进程”时,只创建task_struct,并要求创建出来的task_struct和父task_struct共享进程地址空间和页表

在这里插入图片描述

此时我们创建是四个线程:

  • 其中每一个线程都是当前进程里面的一个执行流,也就是我们常说的“线程是进程内部的一个执行分支”
  • 同时我们也可以看出,线程在进程内部运行,本质就是线程在进程地址空间内运行,也就是几乎都是被所有线程共享的

所以,线程就是一个没有独立的地址空间的task_struct结构,线程的资源是从最开始的主线程,也就是进程来的

CPU调度的是task_struct,并不关心此task_struct是进程的还是线程的,所以线程被称为系统调度的基本单位.而在Linux操作系统下,线程就是轻量化的进程

线程和进程的区别和联系

线程有下面的信息

  • 线程ID
  • 一组寄存器
  • errno
  • 信号屏蔽字
  • 调度优先级

进程的多个线程共享 同一地址空间,因此Text Segment、Data Segment都是共享的,如果定义一个函数,在各线程中都可以调用,如果定义一个全局变量,在各线程中都可以访问到,除此之外,各线程还共享以下进程资源和环境:

  • 文件描述符表
  • 每种信号的处理方式(SIG_ IGN、SIG_ DFL或者自定义的信号处理函数)
  • 当前工作目录
  • 用户id和组id

进程和线程的关系如下图:
在这里插入图片描述

那我们之前说的进程又是什么呢?
在这里插入图片描述

Linux线程控制

POSIX线程库

  • 与线程有关的函数构成了一个完整的系列,绝大多数函数的名字都是以“pthread_”打头的
  • 要使用这些函数库,要通过引入头文<pthread.h>
  • 链接这些线程函数库时要使用编译器命令的“-lpthread”选项

线程ID的本质是一个地址,pthread库是一个动态库,是个第三方库,这个库会被映射到进程的地址空间的共享区中

创建线程

pthread_create函数

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

参数:

  • thread:返回线程ID
  • attr:设置线程的属性,attr为NULL表示使用默认属性
  • start_routine:是个函数地址,线程启动后要执行的函数
  • arg:传给线程启动函数的参数

返回值:

  • 成功返回0
  • 失败返回错误码

例子:

void *route(void *arg) 
{while(1) {printf("I'am a thread \n");sleep(1);}
}
int main()
{pthread_t tid;int ret;if ( (ret=pthread_create(&tid, NULL, rout, NULL)) != 0 ) {fprintf(stderr, "pthread_create : %s\n", strerror(ret));exit(-1);}while(1) {printf("I'am main thread\n");sleep(1);}return 0;
}

线程等待

为什么要线程等待???

已经退出的线程,其空间没有被释放,仍然在进程的地址空间内
创建新的线程不会复用刚才退出线程的地址空间

pthread_cancel函数

int pthread_join(pthread_t thread);

参数:

  • thread:线程ID
  • value_ptr:它指向一个指针,后者指向线程的返回

返回值:

  • 成功返回0
  • 失败返回错误码

线程终止

  • 从线程函数return。这种方法对主线程不适用,从main函数return相当于调用exit
  • 线程可以调用pthread_ exit终止自己
  • 一个线程可以调用pthread_ cancel终止同一进程中的另一个线程

pthread_exit函数

void pthread_exit(void *value_ptr);

参数:

  • value_ptr:value_ptr不要指向一个局部变量

返回值:

  • 无返回值,跟进程一样,线程结束的时候无法返回到它的调用者

pthread_cancel函数

int pthread_cancel(pthread_t thread);

参数:

  • thread:线程ID

返回值:

  • 成功返回0
  • 失败返回错误码

常使用return终止进程

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>void* Routine(void* arg)
{char* msg = (char*)arg;int count = 0;while (count < 10){printf("I am %s---pid: %d, ppid: %d\n", msg, getpid(), getppid());sleep(1);count++;}return NULL;
}
int main()
{pthread_t tid[5];for (int i = 0; i < 5; i++){char* buffer = (char*)malloc(64);sprintf(buffer, "thread %d", i);pthread_create(&tid[i], NULL, Routine, buffer);printf("%s tid is %lu\n", buffer, tid[i]);}printf("I am main thread...pid: %d, ppid: %d\n", getpid(), getppid());for (int i = 0; i < 10; i++){pthread_join(tid[i], NULL);printf("thread %d[%lu]...quit\n", i, tid[i]);}return 0;
}

线程分离

  • 默认情况下,新创建的线程是joinable的,线程退出后,需要对其进行pthread_join操作,否则无法释放资源,从而造成系统泄漏
  • 如果不关心线程的返回值,join是一种负担,这个时候,我们可以告诉系统,当线程退出时,自动释放线程资源

pthread_detach函数

int pthread_detach(pthread_t thread);

自己分离
pthread_detach(pthread_self());

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>void *thread_run( void * arg )
{pthread_detach(pthread_self());printf("%s\n", (char*)arg);return NULL;
} int main( void )
{pthread_t tid;if ( pthread_create(&tid, NULL, thread_run, "thread1 run...") != 0 ) {printf("create thread error\n");return 1;} int ret = 0;sleep(1);// 让线程先分离,再等待if ( pthread_join(tid, NULL ) == 0 ) {printf("pthread wait success\n");ret = 0;} else {printf("pthread wait failed\n");ret = 1;} return ret;
}

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

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

相关文章

python用selenium网页模拟时无法定位元素解决方法1

进行网页模拟时&#xff0c;有时我们明明可以复制出元素的xpath&#xff0c;但是用selenium的xpath click无法点击到元素。这种情况有几种原因&#xff0c;本文写其中一种——iframe 比如下图网址&#xff0c;第二行出现iframe&#xff0c;则往下的行内元素都会定位不到&#…

编程语言:创新的例子——解构技术与艺术的交融

编程语言&#xff1a;创新的例子——解构技术与艺术的交融 在数字化时代的浪潮中&#xff0c;编程语言作为技术领域的核心要素&#xff0c;其创新步伐从未停歇。本文将通过四个方面、五个方面、六个方面和七个方面&#xff0c;深入探讨编程语言创新的例子&#xff0c;揭示技术…

2024最新最全【Java】全栈,零基础入门到精通

Java基础 本文章是作者的学习笔记&#xff0c;帮助初学者快速入门&#xff0c;内容讲的不是很细&#xff0c;适合初学者&#xff0c;不定时更新。 目录 Java基础数据类型1.基本类型(primitive type)1-1 整数类型1-2 浮点类型1-3 字符类型1-4 boolean类型 2.引用数据类型3.类型…

sap 批量创建销售订单

1.首先通过excel编辑好数据 2.tcode&#xff1a;smw0上传到服务器 3&#xff1a;tcode&#xff1a;se38执行代码 源代码如下链接&#xff1a; https://download.csdn.net/download/sinat_29663077/89531998?spm1001.2014.3001.5503

第9集《修习止观坐禅法要》

请大家打开讲义第二十二面&#xff0c;丁二、诃欲第二。 智者大师把这个止观的修行&#xff0c;分成十科。前面的五科是一个前方便&#xff0c;叫做天台二十五方便。这个方便当中的修行呢&#xff0c;这个地方是属于第二科、诃欲。 那么这个诃&#xff0c;就是诃责&#xff0…

java:将集合中的数据放到文件中

代码实现目标&#xff1a; 将集合中的数据写道文件中通过字符缓冲输出流实现 代码展示 public static void main(String[] args) throws IOException {//创建ArrayList集合ArrayList<Student> array new ArrayList<>();//创建学生对象Student s1 new Student(&…

面试总结-基础js

一、变量提升&#xff08;函数里面先形参赋值&#xff0c;再变量提升&#xff0c;最后执行代码&#xff09; 1、概念&#xff1a;当浏览器开辟出供代码执行的栈内存后&#xff0c;代码并没有自上而下立即执行&#xff0c;而是继续做了一些事情&#xff0c;把当前作用域所有带v…

python程序打包成.exe

python程序打包成.exe 安装 PyInstaller打包 Python 程序PyInstaller 命令选项生成的文件示例注意事项 将 Python 程序打包成 .exe 文件&#xff0c;可以使用 PyInstaller。PyInstaller 是一个非常流行的工具&#xff0c;可以将 Python 程序及其所有依赖项打包成一个独立的可执…

【前端】有时候你可能需要SSE而不是WebSocket

深度解析&#xff1a;轮询、SSE 和 WebSocket 在构建实时应用时&#xff0c;开发者面临多种选择&#xff0c;其中最常见的是轮询&#xff08;Polling&#xff09;、服务器推送事件&#xff08;Server-Sent Events&#xff0c;SSE&#xff09;和 WebSocket。本文将深入解析这三…

kind kubernetes(k8s虚拟环境)使用本地docker的镜像

kubernetes中&#xff0c;虽然下载镜像使用docker&#xff0c;但是存储在docker image里的镜像是不能被k8s直接使用的&#xff0c;但是kind不同&#xff0c;可以使用下面的方法&#xff0c;让kind kubernetes环境使用docker image里的镜像。 kind – Quick Start 例如&#x…

华为机考真题 -- 螺旋数字矩阵

题目描述&#xff1a; 疫情期间&#xff0c;小明隔离在家&#xff0c;百无聊赖&#xff0c;在纸上写数字玩。他发明了一种写法&#xff1a;给出数字 个数 n 和行数 m&#xff08;0 < n ≤ 999&#xff0c;0 < m ≤ 999&#xff09;&#xff0c;从左上角的 1 开始&#x…

M12电源分配器:高效率与可靠性的工业解决方案

关键词&#xff1a;M12电源分配器、M12电源接线盒、M12电源分线盒 摘要 M12电源分配器是工业环境中实现高效与可靠电源管理的现代化解决方案。该设备采用坚固的金属外壳和封闭式设计&#xff0c;保证了在严苛工业条件下的稳定运行&#xff0c;达到IP67等级的防护性能&#xf…

NumPy提供了哪些高级的数学和数值计算功能

NumPy&#xff08;Numerical Python&#xff09;是Python中用于科学计算的基础库&#xff0c;它提供了高性能的多维数组对象&#xff08;ndarray&#xff09;以及一系列用于操作这些数组的数学和数值计算功能。以下是NumPy提供的一些高级的数学和数值计算功能&#xff1a; 1. …

FastAPI 学习之路(三十八)Static Files

如果使用前后台不分离的开发方式&#xff0c;那么模版文件中使用的静态文件&#xff0c;比如css/js等文件的目录需要在后台进行配置&#xff0c;以便模版渲染是能够正确读取到这些静态文件的。那么我们如何处理呢&#xff1f; 首先安装依赖 pip install aiofiles 我们看下如何…

蓝队必备技能--yara-让自己编写AVVT

&#x1f3bc;个人主页&#xff1a;金灰 &#x1f60e;作者简介:一名简单的大一学生;易编橙终身成长社群的嘉宾.✨ 专注网络空间安全服务,期待与您的交流分享~ 感谢您的点赞、关注、评论、收藏、是对我最大的认可和支持&#xff01;❤️ &#x1f34a;易编橙终身成长社群&#…

51单片机STC89C52RC——16.1 五线四相步进电机

目录 目的/效果 一&#xff0c;STC单片机模块 二&#xff0c;步进电机 2.2 什么是步进电机&#xff1f; 2.2.1 步进电机驱动板 静态参数 动态参数 2.2.2 五线四相 单相激励步进 双相激励步进 混合激励驱动 2.3 细分驱动 2.4 通过数字信号控制旋转位置和转速。 2…

金蝶云苍穹-插件开发(四)GPT开发相关插件

我只对GPT开发的相关插件进行讲解&#xff0c;因为我的是插件开发教程&#xff0c;关于GPT的一些提示词的写法&#xff0c;GPT任务的配置&#xff0c;请去金蝶云苍穹的文档和社区内学习。 GPT自定义操作 GPT自定义操作的代码的类要实现 IGPTAction 这个接口&#xff0c;这个接…

基于Java+Vue的场馆预约系统源码体育馆羽毛球馆篮球馆预约

市场前景 市场需求持续增长&#xff1a;近年来&#xff0c;随着人们生活水平的提高和休闲娱乐需求的多样化&#xff0c;各类场馆&#xff08;如体育馆、图书馆、博物馆、剧院等&#xff09;的访问量不断增加。然而&#xff0c;传统的预约方式往往存在效率低下、信息不透明等问…

AI算力中心研究分析

中国 AI 算力中心研究报告 算力产业稳健发展&#xff0c;算力创新能力持续增强&#xff0c;推动我国数字经济量质齐升。 2022 年我国算力规模稳步扩张&#xff0c;算力发展为拉动我国 GDP 增长做出突出贡献&#xff0c;在 2016-2022 年期间&#xff0c;我国算力规模平均每年增…

杰林码哈希算法JavaScript源码和Html用法

一、什么是JLMHA &#xff08;1&#xff09;理论来源 JLMHA是指杰林码哈希算法&#xff0c;论文出处为&#xff1a; Hash Algorithm with Adaptive Hash Value Length Based on Weighted Probability Model 论文中有论函数、安全策略等方案&#xff0c;我以前的CSDN博客也写了…