Linux操作系统-线程

Posted TangguTae

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux操作系统-线程相关的知识,希望对你有一定的参考价值。

初识线程

与进程类似,线程是允许应用并发执行多个任务的一种机制。

进程是承担分配系统资源的基本实体。为了承担系统资源,OS为进程创建了大批的数据结构和大批的内存块以承载该进程的代码和数据。

线程是CPU调度的基本单位,线程是进程里面的一条执行流。

每个线程共享同一个地址空间(进程地址空间)。

下图为一个进程的地址空间,此时一个进程有多个线程

(图来自于Linux-UNIX系统编程手册)

为什么要引入线程?

这里就需要说一说线程与进程的区别(优势所在)

1、线程是轻量级进程,创建线程的代价比创建进程的代价要小的多(线程可以直接看到资源,但是进程需要拷贝诸多信息)

2、线程间的通信比较方便。无论是进程间通信还是线程间通信,都需要看到同一块资源才行,对于多个线程来说直接可以看到进程的资源(全局、堆等等)。但是进程与进程之间是独立的,想要通信需要借助额外的方式即IPC(管道、共享内存等)。

3、线程间的上下文切换一般比进程的切换要短。

虽然说线程的缺点也很明显,放到后面在讲。

Linux下线程的接口

依赖第三方库函数<pthread.h>

1、创建线程

pthread_create

第一个参数是输出型参数,用来返回线程的ID,类型是pthread_t,为该线程的唯一标识。

第二个参数为指定新线程的一些属性,设置为NULL表示使用默认属性。

第三个参数为一个函数指针,即让这个线程去执行什么功能,这个函数具有一个形参,属性为void*类型,返回值也为void*。

第四个参数arg即函数入口想要传入的参数。

成功创建返回0,否则返回对应的错误码。

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


void* fuc(void* arg)

  char* str = (char*)arg;
  while(1)
  
    cout<<str<<" "<<pthread_self()<<endl;
    sleep(1);
  
  return NULL;

int main()


  pthread_t pid;
  pthread_create(&pid,nullptr,fuc,(void*)"thread 1");
  while(1)//主线程一旦退出,进程终止
  
    cout<<"i am main thread and thread 1 id is "<<pid<<endl;
    sleep(1);                                                               
  
  return 0;


获取线程ID函数

pthread_self();

这个ID是pthread库用来分配和维护,用来标识线程,类型为无符号长整型,实际上的意义是线程控制块的起始地址。这个ID是用户所看到的。

后面还会出现一个ID是gettid()所获取到的ID,这个ID是Linux内核分配的,这个ID指的是LWP(lighting weight process)轻量级进程。用ps -aL查看。

每一个线程的用户层面的ID对应一个内核级别的LWP。

操作系统真正调度的是LWP对应的数据结构。

2、线程的资源回收

与进程类似,当一个线程退出时也需要进行资源的回收,不然会产生僵尸线程。

第一个参数为thread ID,第二个参数是一个输出型参数,返回线程退出码。

如果线程未分离(pthread_detach) ,则必须得pthread_join来回收线程资源,否则会产生僵尸线程,僵尸线程会浪费系统资源,内存泄漏,且有可能会导致无法创建新线程。

这个过程和进程退出时的wait或者waitpid很相似,但是有一定的区别

1、pthread_join可以连接任意的线程,因为同一个进程下线程的关系式对等的。但是唯一能对子进程调用wait的是父进程。

2、pthread_join无法连接到任意的线程,必须指定一个线程ID,但是waitpid可以等待任意进程waitpid(-1, &status, options)。

3、线程的退出

线程退出的方式

1、函数执行结束,return语句返回指定值

2、调用pthread_exit

3、调用pthread_cacel

注意exit退出是退出一个进程。

主线程退出,进程结束,资源回收,其他线程也会退出。

4、线程的分离

pthread_detach

 

一旦线程退出时,不需要pthread_join来获取其状态,并回收资源。这样可以让线程退出时自动释放资源。

补充:

各线程还共享以下进程资源和环境:

1、文件描述符表

2、信号处理方式

3、当前工作目录

4、用户id和组id

各线程所独有的数据

1、线程ID

2、各自的栈空间

3、errno

4、一组寄存器(线程切换信息)

线程的缺点

1、线程安全问题

2、健壮性较低

3、大量的线程带来更大的开销(同步的开销)

4、编程难度大

以上是关于Linux操作系统-线程的主要内容,如果未能解决你的问题,请参考以下文章

Java线程与Linux内核线程的映射关系(转)

Linux系列:多进程多线程与CPU的关系

Linux最大线程数限制及当前线程数查询

线程基础,JavaSE部分

linux服务器CPU占用率800%左右...

Android Service和Thread的关系