Linux-线程学习(上)

2023-11-01

本文导航:

内容 所占百分比
线程概念 40%
线程与进程区别与联系 20%
线程优缺点 10%
线程控制(创建,终止,等待) 30%

线程的概念

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

我们写的程序从硬盘加载到内存开始运行时,进程就产生了。也就是操作系统开始为这个程序创建PCB,分配系统资源,比如分配一块虚拟地址空间,一个页表,一块物理内存。当这个进程内部有多个执行流时,现在我们可以简单理解父进程用vfork()创建了多个子进程时,这些子进程也需要资源。如果能分得资源就会独自分的资源,但如果分不了就共享。共享一块地址空间。共享一个页表和一块物理内存。

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

这里写图片描述

在这张图中,有3个PCB,在以前的认知里,我们叫做3个进程。


现在我们需要引入线程的概念。

线程概念

  • 线程是一个进程内部的控制序列。控制序列可以理解为一个执行流。进程内部是指虚拟地址空间

  • 一个进程至少有一个线程。这个时候可以粗略理解为进程就是线程。

进程到线程

  • 进程:承担分配系统资源的实体
  • 线程:共享进程所获得资源

这里写图片描述


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

图中3个PCB ,我们就要把他们称之为3个线程了。因为这是在进程里的3个执行控制流。他们共享一块虚拟地址空间。一块页表,所以这3个线程所看到的物理类存也是一样的。但是他们可以执行各自的任务,并有自己生命特征。

所以在图中,进程就是创建执行代码,创建PCB,申请资源,分配资源的实体,即整个图。而线程就是那些单个PCB,在线程中称之为TCB。
或许下面这张图有助于来理解。

这里写图片描述

线程特点
  • 线程是资源竞争的基本单位。
    操作系统有很多资源。进程与进程之间要竞争操作系统资源,当一个进程申请得到一大堆资源。而这些资源又会分配给线程。一个进程内部有多个线程,去竞争进程所获得的资源。所以说线程是资源竞争的基本单位。

  • 线程是程序执行的最小单位
    当用户让进程去执行某个任务时,进程又会将任务细化。进程内部有很多线程,让这些线程去执行

  • 线程共享进程数据,但也拥有自己独立的一部分数据: 线程ID ,一组寄存器,栈,errno值,信号。

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

这里写图片描述

进程的多个线程共享

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

  • 文件描述符表
  • 每种信号的处理方式(SIG_IGN、SIG_DFL或者自定义的信号处理函数),也就是Hdanle表
  • 当前工作目录

进程与线程联系

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

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

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

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

这里写图片描述


线程的优点
  • 创建一个新线程的代价要比创建一个新进程小得多,释放成本也更低。因为创建一个进程就意味着要创建PCB,分配虚拟地址空间,页表,物理内存等系统资源,而创建一个线程只需要创建一个PCB(TCB)即可

  • 与进程之间的切换相比,线程之间的切换需要操作系统做的工作要少很多。进程切换,需要切换对应的虚拟地址空间,更换页表等。过程繁琐。

  • 线程占用的资源要比进程少很多

  • 能充分利用多处理器的可并行数量。

  • 在等待慢速I/O操作结束的同时,程序可执行其他的计算任务。比如打开一个网易云音乐播放器,你可以一边下载,一边在线听歌。这就是两个线程在工作。

  • 计算密集型应用,为了能在多处理器系统上运行,将计算分解到多个线程中实现 I/O密集型应用,为了提高性能,将I/O操作重叠。线程可以同时等待不同的I/O操作。
    进程可以将线程串行执行变成并行执行。最后汇总,提高效率。但是尽量不要创建太多线程,线程切换也是需要成本的。


线程的缺点
  • 性能损失

    一个很少被外部事件阻塞的计算密集型线程往无法与共它线程共享同一个处理器。如果计算密集型线程的数量比可用的处理器多,那么可能会有较大的性能损失,这里的性能损失指的是增加了额外的同步和调度开销,而可用的资源不变。

  • 健壮性降低

    编写多线程需要更全面更深入的考虑,在一个多线程程序里,因时间分配上的细微偏差或者因共享了不该共享的变量而造成不良影响的可能性是很大的,换句话说线程之间是缺乏保护的。一个线程挂掉,因为线程共享一块资源。其他线程也会挂掉。进而导致进程退出,资源被回收。

  • 缺乏访问控制

    进程是访问控制的基本粒度,在一个线程中调⽤用某些OS函数会对整个进程造成影响。多线程访问临界资源,它的访问控制是由编程者决定。

  • 编程难度提高

    编写与调试一个多线程程序比单线程程序困难得多,基于同步互斥。你需要不断的加锁,


线程控制

POSIX线程库

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

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

这里写图片描述

创建线程

调用函数
这里写图片描述

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


错误检查:

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

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

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

#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
//新线程的例程(执行任务,打印字符串)
void * my_run(  void *arg)
{
      while(1)
      {

            printf(  "  i am %s\n",(  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 thread\n");
            sleep(2);
      }
      return 0;
}

这里写图片描述

pthread_create创建成功!
主线程和新线程各自打印不同的内容。

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


终止线程

如果需要只终止某个线程而不终止整个进程,可以有以下方法:

  • 从线程函数return。这种方法对主线程不适用,从main函数return相当于调用exit。
void * my_run(  void *arg)
{
      while(1)
      {

            printf(  "  i am %s\n",(  char *)arg);

            sleep( 1);
            return NULL;

      }
}

这里写图片描述

新线程终止,主线程继续执行。
- 线程可以调用pthread_ exit终止自己。

pthread exit函数

功能:线程终止

 #include <pthread.h>

 void pthread_exit(void *retval);

参数

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

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

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
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:%d\n",tid,*(int *)ret);
      free(ret);


      while(1)
      {
            printf("i am main thread\n");
            sleep(2);
      }
      return 0;
}

这里写图片描述

,pthread exit或者return返回的指针所指向的内存单元必须是全局的或者是用malloc分配的,不能在线程函数的栈上分配,因为当其它线程得到这个返回指针时线程函数已经退出了。

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

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

  • 一个线程可以调用pthread cancel终止同一进程中的另一个线程。

pthread_cancel函数

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

#include <pthread.h>

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)
      {

        printf("thread  return,id is:%ld,return code:PTHREAD_CANCELED\n",tid);

      }
      else
      {

        printf("thread  return,id is:%ld,return code:NULL\n",tid);
      }

      return 0;
}

这里写图片描述

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

 #include <pthread.h>

 pthread_t pthread_self(void);

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

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

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


线程等待

为什么需要线程等待?

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


功能:等待线程结束原型

int pthread_join(pthread_t thread, void **value ptr);

参数

thread:线程ID

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


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

如果thread线程通过return返回,value ptr所指向的单元⾥里存放的是thread线程函数的返回值。

如果thread线程被别的线程调⽤用pthread cancel异常终掉,value_ ptr所指向的单元里存放的是常数

PTHREAD CANCELED。

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

如果对thread线程的终止状态不感兴趣,可以传NULL给value_ ptr参数。

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

线程分离
  • 在默认情况下,新线程默认是joinable的。线程退出后,需要对其进行pthread_join操作来回收资源,否则无法释放资源,造成内存泄露。

  • 如果不关心线程的返回值,join就是一种负担。线程提供一种自动回收的方法,叫做线程分离。当线程分离,退出后,自动释放线程资源。

线程分离接口

  • 线程组类其他线程对目标线程进行分离
#include <pthread.h>
int pthread_detach(pthread_t thread);
  • 线程自我分离
#include <pthread.h>
int pthread_detach(pthread_t self());

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

线程被分离后,就不能在进行pthread_join()操作。否则会出错。因为分离后的线程资源自动就被回收了,再进行等待回收资源。必定导致等待失败。

测试用例如下

#include <stdio.h>
#include <stdlib.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(  )
{
      pthread_t tid;
      if(  pthread_create(&tid,NULL,thread_run,"thread1 run...")!=0)
      {
            printf("create thread error\n");
            return 1;
      }
      //主线程分离新线程
      //pthread_detach(tid);
      int ret=0;
      sleep(1);
      if(  pthread_join(  tid,NULL)==0)
      {
            printf("wait thread success\n");
            ret=0;
      }
      else
      {
            printf("wait thread failed\n");
            ret= 1;
      }
      return ret;

}

这里写图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux-线程学习(上) 的相关文章

  • 计算机网路基础 - 一些基本概念与网络结构

    1 基本概念 计算机网络 通信技术 计算机技术 是两项技术紧密结合的产物 通信系统的基础模型 计算机网络 是指将地理位置不同 具有独立功能的多台计算机及其外部设备 通过通信线路连接 在网络操作系统 网络管理软件及网络通信协议的管理和协调下
  • java调优总结

    JVM调优总结 序 几年前写过一篇关于JVM调优的文章 前段时间拿出来看了看 又添加了一些东西 突然发现 基础真的很重要 学习的过程是一个由表及里 再由里及表的过程 呵呵 所谓的 温故而知新 而真正能走完这个轮回的人 也就能称为大牛或专家了
  • 文件管理系统(操作系统)——9张思维导图

    文件管理系统 1 文件管理 1 1 一个文件的逻辑结构 比如一个文本txt文件 又或者Excel文件 在我们用户看来 它是长什么样的 这个就是逻辑结构 几个概念 逻辑结构 就是指在用户看来 单个文件内部的数据应该是如何组织起来的 物理结构
  • Win11微软账号登录不上?Win11登录Microsoft账户出错的解决方法

    Win11微软账号登录不上 近期有部分Win11用户反映在登录微软账号会出现一直转圈 无法登录的情况 这样导致部分功能都不能正常使用了 为此十分令人头疼 那么对于这一情况 有没有什么方法可以有效的解决呢 下面小编教给大家操作方法 大家可以去
  • Linux系统的安装(在VM虚拟机上安装CentOS 7)

    工具准备 物理计算机一台 配置要求 操作系统 win10 64位 大家基本上都是 硬盘可用容量 20G以上 内存容量 4G以上 虚拟机安装包 VMware workstation full 12 5 下载链接 点我下载 提取码 9gha C
  • redis主从同步,总是显示master_link_status:down的解决方法

    前几天 在修改一台从节点的redis的监听端口后 重启了下redis 发现master link status 很长时间一直都是down状态 查看了redis日志 发现日志里出现很多的 I O error trying to sync wi
  • mapengpeng1999@163.com 操作系统4~处理机调度

    处理机调度 1 三级调度体系 1 处理机调度主要是对处理机运行时间进行分配 即 按照一定算法或策略 将处理机运行时间分配给各个并发进程 同时尽量提高处理机的使用效率 2 现代操作系统中 按调度所实现的功能分3种类型 高级调度 中级调度和低级
  • 虚拟内存的最大容量与实际容量区别

    虚拟内存的最大容量与实际容量区别 1 概念介绍 虚拟内存的最大容量是计算机的地址结构 CPU寻址范围决定的 虚拟内存的实际容量是内存与外存之和 CPU寻址范围 两者的最小值 2 例题介绍 某计算机的地址结构是64位 按字节编址 内存大小51
  • Ubuntu 10.10下安装TFTP的步骤 tftp-hpa版本

    背景 由于想要在tq2440板子上用tftp下载kernel 所以要在自己的PC机的Ubuntu 10 10上安装tftp服务 所以就去网上找了些教程 但是很悲剧 按照那些教程去操作 结果还都是无法正常运行tftp服务 最后还是从一个外国人
  • Linux 磁盘与文件系统管理(鸟哥私房菜)

    本文来自 http vbird dic ksu edu tw linux basic 0230filesystem php 第八章 Linux 磁盘与文件系统管理 系统管理员很重要的任务之一就是管理好自己的磁盘文件系统 每个分割槽不可太大也
  • Linux系统编程:多线程交替打印ABC

    引言 分享关于线程的一道测试题 因为网上基本都是Java的解决方法 决定自己写一篇来记录一下线程的学习 问题描述 编写一个至少具有三个线程的程序 称之为线程 A B 和 C 其中线程 A 输出字符 A 线程 B 输出字符 B 线程 C 输出
  • Linux,Network manager 导致节点异常重启

    推断是Network manager 导致的 原因待查今天在VmWare的虚拟机上装了个测试RAC 又遇到了一个摸不到头绪的问题CRS装好后 一旦登陆图形界面 节点就重启 事情就有这么巧不登陆图形界面 观察了1个小时没问题 一旦登陆后 立刻
  • 操作系统 段页式存储管理

    一 引入 分页系统是以页面作为内存分配的基本单位 能有效地提高内存利用率 但信息共享等不方便 分段系统是以段作为内存分配的基本单位 它能够更好地满足用户多方面的需要 信息共享 动态链接等 但采用分区方式管理物理内存 仍然存在碎片问题 段页式
  • 通过源码包*.src.rpm定制开发rpm

    为什么80 的码农都做不了架构师 gt gt gt 1 基本流程 1 下载 安装相应的src rpm包 wget xxx src rpm rpm ivh xxx src rpm 这里的 安装 是指把xxx src rpm中的tar gz p
  • Visual studio 2005 hangs on startup AppHangXProcB1 svchost devenv.exe svchost.exe:{2a811bb2-303b-48b...

    This problem has been torturing me for the whole afternoon and after searching on the web for a long time I finally get
  • Linux常用命令记录

    文章目录 1 软件安装 安装软件 来自源服务器 安装 deb软件 来自本地 deb文件 修复依赖关系 卸载软件 2 文件 文件夹操作 删除文件夹 移动文件 文件重命名 3 程序查看 处理 进程查看 查看端口占用情况 强制终止程序 4 解压文
  • Linux 内核中的 Device Mapper 机制

    Linux 内核中的 Device Mapper 机制 尹 洋 在读博士生 尹洋 中科院计算所国家高性能计算机工程技术研究中心的在读博士生 主要从事服务部署和存储资源管理以及Linux块设备一级的开发和研究工作 简介 本文结合具体代码对 L
  • 磁盘调度算法笔记和练习题

    磁盘调度算法 先来先服务FCFS 最短寻道时间优先SSTF 扫描调度SCAN 练习题 先来先服务FCFS 最短寻道时间优先SSTF 扫描调度SCAN 它是一次只响应一个方向上的请求 这个方向上的请求都响应完了 再掉头处理另一个方向上的 有点
  • CentOS Linux服务器安全设置

    转自 http www osyunwei com archives 754 html 引言 我们必须明白 最小的权限 最少的服务 最大的安全 所以 无论是配置任何服务器 我们都必须把不用的服务关闭 把系统权限设置到最小话 这样才能保证服务器
  • 老生常谈问题之——进程和线程的关系和区别

    最初 我们在学习进程和线程的时候都是和操作系统的知识相关的 但是我们前端菜鸟除了面试的时候很少用到他们 所以我们还是从前端常见的场景来详细的学习进程和线程吧 在前端提到关于进程和线程的概念主要有以下几个场景 1 js 是单线程的编程语言 也

随机推荐

  • 数据结构与算法c语言版胡明课后答案,算法设计与分析(第2版) 王红梅 胡明 习题答案...

    O N x 2 O N 2 2 x a O N x a 2 O N 2 x x 2 a O N 2 a 1 x 由此可知 时间复杂度可达到O n 3 分治策略一定导致递归吗 如果是 请解释原因 如果不是 给出一个不包含递归的分治例子 并阐述
  • @PathVariable接收两个参数

    首先 PathVariable无法接收对象 但是可以接收多个值 var data obj data if obj event edit var tmpData encodeURI JSON stringify data layer open
  • vue_前后端分离-增删改操作

    增加操作和修改操作 两个操作放一个页面进行操作 使用插槽 scope row 的方式获取列表中的每一行数据
  • 在Android上实现SPI通信之(1)------在Ubuntu12.04环境下编译android源码

    作为一个Android应用开发者 突然接到一下需求 需要在应用层传递一个信号到外设 传递方式用SPI通信 没有做过 甚是头大 遇到了好多坑 所以记录成册 希望对后来的开发者 有那么一点点的帮助 如果有不正确的地方 还请指正 目前我实现的大体
  • 数据结构-图篇

    数据结构 图篇 内容 思维导图 基于教材 错题复盘 计算题 基于习题解析 课后习题 1 思维导图 2 错题复盘 计算题 1 具有n个顶点的有向图最多有 B 条边 A n B n n 1 C n n 1 D n 2 解析 对于有n个顶点的有向
  • 机器学习:python实践 回归项目实例 学习记录

    导入类库 import numpy as np import pandas from numpy import arange from matplotlib import pyplot from pandas import read csv
  • 微信小程序原生开发学习01

    文章目录 一 起步 1 注册一个小程序账号 2 下载安装开发者工具 3 新建小程序项目 二 小程序配置 1 全局配置 1 小程序默认启动页 2 页面路径列表 3 分包
  • 字符串的数字部分加1操作

    字符串如通天塔001 10002 Test990 public static String addOne4Str String str if str null int fIndex 1 for int i 0 i lt str length
  • 2022搭建企业级数据治理体系

    数据治理是企业数据建设必不可少的一个环节 好的数据治理体系可以盘活整条数据链路 最大化保障企业数据的采集 存储 计算和使用过程的可控和可追溯 如何构建企业数据治理体系 企业数据治理过程需要注意哪些问题 总体而言 不能一口一个胖子 路要一步一
  • Pycharm乱码解决大全

    一 运行项目时控制台乱码 最直观的方法就是改控制台的默认编码方式 如果不行 就在Settings的Editor里点击FileEncoding 在下图中三个位置修改编码一致 一般为UTF 8或者GBK 最后Apply并确认后重新运行项目即可
  • 测试用例具体设计方法

    目录 一 根据需求写测试用例 二 测试用例具体的设计方法 1 等价类 2 边界值 3 因果图法 4 正交法 5 场景法 6 错误猜测法 一 根据需求写测试用例 1 首先要保证需求的合理性和正确性 要先验证需求 2 分析需求 把大需求细化成小
  • 机器如何识别花的种类

    惊蛰已过 一声春雷 大地开始解冻 条件允许的话 出去晒晒太阳 看看风景 赏赏花 也可以在央视直播云赏花 十多个机位展示了全国各地不同地区的美丽风景 形色 看到好看的花 但是叫不上名字怎么办 这里推荐一下 形色 一款小众的识花应用 带你遇见全
  • 使用arcpy导出要素类和删除要素类中的要素数据

    需求 目的是在指定的GDB数据库中 将要素数据集SourcePolygon下的北京图层中的Layer字段值等于 KZ 控制指标 的记录先导出到新创建的TempPolygon下 导出的图层名为 ControlIndex 然后再将北京图层中的L
  • java知识点——case

    A continue statement can be used only in a loop continue语句只能在循环中使用 A break statement can t be used only in a loop break语
  • 【计算机视觉

    文章目录 一 检测相关 9篇 1 1 Federated Ensemble YOLOv5 A Better Generalized Object Detection Algorithm 1 2 Zero shot Nuclei Detect
  • 使用WinDbg Preview 查看Windows 10蓝屏Dump文件

    从应用商店安装WinDbg Preview 1 登陆应用商店 搜索WinDbg Preview 2 选择获取 我的Windows 10 系统已经安装过了 3 在启动菜单可以找到WinDbg Preview 4 找到蓝屏文件 并选择使用Win
  • 【Github】错误解决:OpenSSL SSL_read: Connection was reset, errno 10054

    git 报错信息 OpenSSL SSL read Connection was reset errno 10054 Git 中 push 或者 pull 报错 OpenSSL SSL read Connection was reset e
  • arthas的trace、watch、tt、profiler命令的使用

    arthas的trace watch tt profiler命令的使用
  • 通过C语言实现小数整数求原码,反码,补码

    通过C语言实现小数 整数求原码 反码 补码 判断输入的值是整数还是小数 是正是负 求纯整数不含符号的原码 求纯小数不含符号的原码 完善整个原码 符号 小数 整数合在一起 将求原码的函数封装在一个函数里 求反码的函数 求补码的函数 main函
  • Linux-线程学习(上)

    本文导航 内容 所占百分比 线程概念 40 线程与进程区别与联系 20 线程优缺点 10 线程控制 创建 终止 等待 30 线程的概念 谈到线程 我们先从进程说起 我们写的程序从硬盘加载到内存开始运行时 进程就产生了 也就是操作系统开始为这