LinuxGod

LinuxGod.net
Linux大神网——精选每一篇高品质的技术干货
  1. 首页
  2. 开源快讯
  3. 正文

共享一个页表和一块物理内存的区别与联系导航

2023年2月12日 365点热度

本文导航:

内容所占比率

线程概念

40%

线程与进程区别与联系

20%

线程异同点

10%

线程控制(创建,中止,等待)

30%

线程的概念

提到线程,我们先从进程说起。

我们写的程序从硬碟加载到显存开始运行时,进程就形成了。也就是操作系统开始为这个程序创建PCB,分配系统资源,例如分配一块虚拟地址空间,一个页表,一块化学显存。当这个进程内部有多个执行流时,如今我们可以简单理解父进程用vfork()创建了多个子进程时linux下socket编程,这种子进程也须要资源。倘若能分得资源都会只身分的资源,但若果分不了就共享。共享一块地址空间。共享一个页表和一块化学显存。

为了易于来理解,我画了一张简明图

这里写图片描述

在这张图中,有3个PCB,在原先的认知里,我们称作3个进程。

如今我们须要引入线程的概念。

线程概念

进程到线程

在明晰线程概念后,我们就要站在线程的角度去理解前面那张图了。

图中3个PCB,我们就要把她们称之为3个线程了。由于这是在进程里的3个执行控制流。她们共享一块虚拟地址空间。一块页表,所以这3个线程所见到的化学类存也是一样的。并且她们可以执行各自的任务linux线程和进程的区别,并有自己生命特点。

所以在图中,进程就是创建执行代码,创建PCB,申请资源,分配资源的实体,即整个图。而线程就是这些单个PCB,在线程中称之为TCB。

其实下边这张图有助于来理解。

线程特征

其中最重要的数据是栈和寄存器。私有栈是为了保存临时变量linux线程和进程的区别,以便函数调用等操作。私有寄存器是为了便捷线程切换,保存上下文。

进程的多个线程共享

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

进程与线程联系

在Linux下并没有专门为线程设计如此一个概念,也就是说没有真正意义上的线程,它在linux下是由进程模拟的,可以觉得所有的PCB都可以称为轻量级进程(不一定是进程,也可能是线程)。进程是分配系统资源的一个实体linux端口映射,而线程是CPU调度的基本单位。

在单个程序中同时运行多个线程完成不同的工作,称为多线程。相对来说,多进程相对稳定,多线程相对不稳定。可以觉得,进程是分配系统资源的一个实体,而线程是CPU调度的基本单位。

进程具有独立的地址空间,而线程并没有,同一进程内部的线程共享进程的地址空间。

因为Linx下没有真正的线程,Linux用进程来描述线程和组织线程。所以在Linux下只有轻量级的线程,操作系统是看不到线程的TCB的。所以右图中的第四个图:多个进程多个线程图中,操作系统可以看见的是6个PCB,

线程的优点线程的缺点线程控制POSIX线程库

与线程有关的函数构成了一个完整的系列,绝⼤大多数函数的名子都是以“pthread_”打头的

要使用这种函数库,要通过引入头文件,链接这种线程函数库时要使用编译器命令的“-lpthread”选项

常见操作如下

这里写图片描述

创建线程

调用函数

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

linux 查看进程线程_linux线程和进程的区别_linux 进程 线程

错误检测:

传统的一些函数是,成功返回0,失败返回-1,但是对全局变量errno形参以指示错误。

pthreads函数出错时不会设置全局变量errno(而大部份其他POSIX函数会这样做)。而是将错误代码通过返回值返回pthreads同样也提供了线程内的errno变量,以支持其它使用errno的代码。对于pthreads函数的错误,建议通过返回值业判断,由于读取返回值要比读取线程内的errno变量的开支更小

测试用例

注意:编译链接时,一定要加上-lpthreead选项,见图中命令部份。由于这是用户级别的库,并不是系统提供的库。

#include 
#include 
#include 
//新线程的例程(执行任务,打印字符串)
void * my_run(  void *arg)
{
      while(1)
      {
            printf(  "  i am %sn",(  char *)arg);
            sleep( 1);
      }
}
int main(  )
{
      //申明一个本地变量tid,用来保存对等线程的ID
      pthread_t tid;
      //调用pthread_create函数创建一个新的线程,
      pthread_create(&tid,NULL,my_run,"newthread");
      //调用结束,同时运行,并且tid包含了新线程的id
      while(1)
      {
            printf(  "  i am main threadn");
            sleep(2);
      }
      return 0;
}

pthread_create创建成功!

主线程和新线程各自复印不同的内容。

正常情况下,一个程序里是不会同时执行两个死循环的。并且,在这个程序里,竟然可以同时执行两个死循环。缘由就在于这时两个线程在运行。各自执行不同的任务,有自己的栈空间和寄存器,支持上下文切换和函数调用。

中止线程

假如须要只中止某个线程而不中止整个进程,可以有以下方式:

void * my_run(  void *arg)
{
      while(1)

linux 查看进程线程_linux 进程 线程_linux线程和进程的区别

{ printf( " i am %sn",( char *)arg); sleep( 1); return NULL; } }

新线程中止,主线程继续执行。

-线程可以调用pthread_exit中止自己。

pthreadexit函数

功能:线程中止

 #include 
 void pthread_exit(void *retval);

参数

valueptr:valueptr不要指向一个局部变量。

返回值:无返回值,跟进程一样,线程结束的时侯难以返回到它的调用者(自身)

#include 
#include 
#include 
#include 
void * my_run(  void *arg)
{
      printf("thread 1 returning ....n");
      int *p=(int *)malloc(sizeof(int));
      *p=1;
      pthread_exit((void *)p);
}
int main(  )
{
      pthread_t tid;
      void *ret;
      //thread 1 exit
      pthread_create(&tid,NULL,my_run,NULL);
      //等待新线程退出,退出码保存在ret中
      pthread_join(tid,&ret);
      printf("thread  return,id is:%ld,return code:%dn",tid,*(int *)ret);

linux线程和进程的区别_linux 查看进程线程_linux 进程 线程

free(ret); while(1) { printf("i am main threadn"); sleep(2); } return 0; }

,pthreadexit或则return返回的表针所指向的显存单元必须是全局的或则是用malloc分配的,不能在线程函数的栈上分配,由于当其它线程得到这个返回表针时线程函数早已退出了。

调用phread_exit(),他会等待所有其他对等线程(就是同一个进程中的除自身外其他线程)中止,之后再中止主线程和整个进程。

假如某个对等线程调用linux的exit函数,则该函数中止进程以及所有与该进程相关的线程

pthread_cancel函数

功能:取消一个执行中的线程

#include 
int pthread_cancel(pthread_t thread);

参数

thread:线程ID

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

void* my_run_2(void* arg)
{
      while(1)
      {
            printf(  "thread 2 is running...n");
            sleep(1);
      }
      return NULL;
}
int main(  )
{
      pthread_t tid;
      void *ret;
      pthread_create(&tid,NULL,my_run_2,NULL);
      sleep(1);
      //取消执行中的线程2
      pthread_cancel(tid);
      //等待线程2的返回状况,获取返回值
      pthread_join(tid,&ret);
      if(ret==PTHREAD_CANCELED)

linux 进程 线程_linux线程和进程的区别_linux 查看进程线程

{ printf("thread return,id is:%ld,return code:PTHREAD_CANCELEDn",tid); } else { printf("thread return,id is:%ld,return code:NULLn",tid); } return 0; }

介绍一个获取当前线程id的函数

 #include 
 pthread_t pthread_self(void);

获取当前文件中线程tid命令

ps -eLf | head -1&& ps -eLf | grep a.out 

以上都是显示中止,另外还有隐式中止。即:顶楼的线程调用返回时,线程会隐式中止。

线程等待

为何须要线程等待?

早已退出的线程,其空间没有被释放,一直在进程的地址空间内。创建新的线程不会复⽤用刚刚退出线程的地址空间。

功能:等待线程结束原型

intpthread_join(pthread_tthread,void**valueptr);

参数

thread:线程ID

value_ptr:它指向一个表针,前者指向线程的返回值返回值:成功返回0;失败返回错误码

调用该函数的线程将挂起等待,直至id为thread的线程中止。thread线程以不同的方式中止,通过pthread_join得到的中止状态是不同的,总结如下:

假如thread线程通过return返回,valueptr所指向的单元⾥里储存的是thread线程函数的返回值。

假如thread线程被别的线程调⽤用pthreadcancel异常终掉,value_ptr所指向的单元里储存的是常数

PTHREADCANCELED。

假如thread线程是自调用pthreadexit中止的,valueptr所指向的单元储存的是传给pthread_exit的参数。

假如对thread线程的中止状态不感兴趣,可以传NULL给value_ptr参数。

测试用例可以参考前面的代码。

线程分离

线程分离插口

#include 
int pthread_detach(pthread_t thread);

#include 
int pthread_detach(pthread_t self());

返回值:都是成功返回0,失败返回-1.

线程被分离后,就不能在进行pthread_join()操作。否则会出错。由于分离后的线程资源手动就被回收了,再进行等待回收资源。必将造成等待失败。

测试用例如下

#include 
#include 
#include  
#include 
void * thread_run(  void *arg)
{
      //新分离线程自我分离
      pthread_detach(pthread_self( ));
      printf("%sn",(  char *)arg);
      return NULL;
}
int  main(  )
{
      pthread_t tid;
      if(  pthread_create(&tid,NULL,thread_run,"thread1 run...")!=0)
      {
            printf("create thread errorn");
            return 1;
      }
      //主线程分离新线程
      //pthread_detach(tid);
      int ret=0;
      sleep(1);
      if(  pthread_join(  tid,NULL)==0)
      {
            printf("wait thread successn");
            ret=0;
      }
      else
      {
            printf("wait thread failedn");
            ret= 1;
      }
      return ret;
}

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: pthread 函数调用 返回值 进程控制块 页表
最后更新:2023年2月12日

Linux大神网

每日更新,欢迎收藏♥ 不积跬步无以至千里,加油,共勉。

点赞
< 上一篇
下一篇 >

Linux大神网

每日更新,欢迎收藏♥
不积跬步无以至千里,加油,共勉。

最新 热点 随机
最新 热点 随机
如何安装便携式WiFi驱动程序?360wifi驱动的教程 CentOS云服务器搭建网站和CentOS搭建DNS解析服务 如何在linux上创建一个用户,减少不必要的沟通成本 如何在Linux系统中查看CPU信息使用lscpu命令行 linux服务器搭建ftp的6下安装vsftpd步骤及步骤 贵州工业职业技术学院求职意向期望工作地--诚聘英才 实验1Linux安装实验掌握虚拟机的使用 Linux系统tar命令的使用方法及使用命令教程 linux 开源nas系统 杰和科技NAS服务器媒体见面会在京召开 Android与Linux开发大不同 Linux系统软件安装包:自己动手,安装不用愁 车市新战局:汽车操作系统会复制智能手机的历史吗? Linux文件系统种类 如何卸载用源码包安装的软件?在线视频教程推荐 「职位」ASP.、PHP、Linux服务器集群开发 Torvalds:Linux内核开发的创新前景充满了热情 Linux文件系统的结构从终端窗口探索Linux目录树结构 卸载软件命令Linux.You linux软件开发如何入门?学习Linux步骤及学习方法介绍 14年Linux发行版的有趣历史观点
嵌入式Linux操作系统学习规划+LINUX路线,主攻江苏电信天翼校园客户端故障指引及解决办法(101)英特尔GMAGMA950显卡驱动程序/WIN8/8.1电信校园网宽带用USB数据线共享给电脑无线上网国防科大开源操作系统:它只是一个吉祥的象征10个常用Linux文本查看命令及其详细说明和使用示例Linux嵌入式系统内核裁剪与定制方法的介绍情况淘宝教育热卖C语言编程开发C++程序设计零基础入门课程从CPU、内存、硬盘、显卡等这些方面安装Linux系统的最低配置Linux通过chkconfig设置开机启动服务创建的几种常见方式(技术分析)Linux多线程的使用与操作系统的区别通常rar命令由一个主命令加若干选项(可选)构成RedHatLinux中自动运行程序中的应用linux 读写文件 关于Linux内核的神秘面纱,你知道几个?使用wget实用程序的有用命令行工具的使用怎么设置linux开机项自启动?方式是怎样的?嵌入式Linux应用层与驱动层要想学习关于Linux内核的交叉编译步骤和方法:步骤、方法STM32嵌入式linux开发流程及应用程序分析-STMlinux下有哪些文件在介绍lsof命令实用用法介绍?
基于嵌入式Linux的智能手机系统软件的设计与实现 教你在XShell软件中使用sz和rz命令下载和上传文件 两台linux 传文件 STM32笔记第二十五章 嵌入式Linux的特点技术支持.3、DellG3 Linux下定时执行脚本的使用方法及解决办法(一) Linux集群技术热点与发展趋势分分: 编程珠玑(shouwangxiansheng)Linux常用命令中有哪些命令? 快速云小编的几种软件是需要安装的。。(一) 虚拟机安装Ubuntu操作系统-Ubuntu空间20G镜像下载 查看Linux系统中ssh版本的方法教你如何查看? 「职位」ASP.、PHP、Linux服务器集群开发 在小米8上使用“原生linux”这条路算是封死了 Linux之Ubuntu一图形桌面与命令行模式相关切换到命令行 如何在linux下操作和查看用户状态和进程状态? ❶以太坊是如何挖矿的以太币 中科红旗(北京)信息科技有限公司研发的Linux桌面操作系统社区预览版 虚拟主机技术极大怎么样?如何选择多个网站.Q. Linux文件系统种类 不同版本的内核源码下载页面介绍:主线版(mainline) 安装Linux和Windows双系统的硬盘分区是什么意思?
标签聚合
linux服务器 文件目录 应用 操作 文件 内核 虚拟机 linux系统 软件 命令
书籍
课程
技术群
技术干货大合集↓
  • 2023年9月 / 81篇
  • 2023年8月 / 93篇
  • 2023年7月 / 94篇
  • 2023年6月 / 90篇
  • 2023年5月 / 93篇
  • 2023年4月 / 90篇
  • 2023年3月 / 129篇
  • 2023年2月 / 84篇
  • 2023年1月 / 161篇
  • 2022年12月 / 187篇
  • 2022年11月 / 76篇
友情链接:

Linux书籍 | Linux命令 | Linux系统 | RHCE红帽认证 | Linux软件 | Linux教程 | CentOS系统 | Linux内核 | Linux服务器 | Linux大神 | IT资源

COPYRIGHT © 2023 linuxgod.net ALL RIGHTS RESERVED.