线程基本概念:

1 线程

  (1)概念:linux下没有真正的线程,所谓的线程都是通过进程的pcb模拟的,因此linux下的线程也称为“轻量级进程”,之前我们所说的进程现在看来,可以理解为:只有一个线程的线程组。也可以将线程理解为:在一个程序里的一个执行路线,更准确的来说,线程是一个进程内部的控制序列

  (2)进程:至少有一个线程的线程组

  (3)linux下的pcb是task_struct,task_struct中的tgid是线程组id,也等于第一个进程的pid,如果再创建新的线程,这些线程的tgid会相同

2 线程和进程

  (1)进程是资源竞争的基本单位

  (2)线程是程序执行的最小单位

  (3)线程共享进程的数据,比如进程的正文段,数据段,文件描述符(代表一个线程打开文件,另一个线程也可以拿着文件描述在安全的前提下进行操作),信号的处理方式,当前工作目录,用户id,组id。但线程也有自己独有的资源:栈,上下文数据,errno全局变量,信号屏蔽字,调度优先级等等。(注:这些独有的数据都存放在虚拟地址空间的共享区)

  (4)进程和线程的关系如下图:

3 线程的优点:

  (1)创建一个线程的代价要比创建一个线程的代价小的多

  (2)与进程之间的切换先比而言,线程之间的切换需要操作系统做的工作很少

  (3)线程占有的资源要比进程小很多

  (4)能充分利用多处理器的可并行数量

  (5)在等待慢速I/O操作结束的同时,程序可执行其他的计算任务

  (6)线程多用于cpu密集型与I/O密集型程序

4 线程的缺点:

  (1)性能损失:在有的情况下会增加额外的调度与同步开销(比如有的操作无法与其他线程共享处理器,当这种操作的数量大于处理器的数量时,会产生这种情况)

  (2)健壮性降低:线程切换之间缺乏安全保护,需要额外的操作保证线程对共享资源的安全访问

  (3)缺乏访问控制:进程是访问控制的基本粒度,在一个线程中调用某些OS函数会对整个进程造成影响

  (4)编程难度较高

线程控制

注意:我们所使用的是大佬们封装的一套接口,因此所使用的都是库函数,所以也说这套接口创建的线程是用户态线程,并且这个用户态线程在操作系统中对应了一个轻量级进程

1 线程创建

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

  参数:第一个参数返回线程id,第二个参数表示要设置线程的属性,第三个参数表示线程启动后要执行的函数,第四个参数表示创个线程启动函数的参数

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

2 线程终止

  void pthread_exit(void *value_ptr);

  参数:输出型参数,带出线程退出时的返回值,不能讲局部变量的地址传给它;

  无返回值

  int pthread_cancel(pthread_t thread);

  功能:同一进程中的其他线程,可以取消另一个线程

  参数:线程id

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

3 线程等待与分离

  (1)需要线程等待的原因:已经退出的线程,其空间没有释放,仍然在进程地址空间中,创建新的线程不会覆盖退出线程的空间,因此为了避免内存泄漏,需要线程等待,获取线程的退出状态,并且允许系统回收资源

  (2)int pthread_join(pthread_t thread, void** value_ptr)

    参数:第一个参数:表示需要等待线程的线程id,第二个参数是输出型参数,指向一个指针,表示线程的退出状态返回值,传NULL表示不关心返回状态

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

  注意:只有线程处于joinable状态,这个线程才能被等待,此状态是线程的默认属性;除此之外,还有detach状态,此状态表示线程退出后直接释放资源,线程无法被等待。线程的这两个属性是互斥的,二者只能选其一

  (3)分离线程:int pthread_detach(pthread_t thread)

    int pthread_detach(pthread_self())

线程的同步与互斥

  大部分情况下,线程使用的数据都是局部变量,变量的地址空间在线程地址空间中,这种情况下,变量归单个线程,其他线程无法获得这种变量;但有时候,很多变量都需要在线程间共享,这样的变量称为共享变量,可以通过数据的共享,完成线程之间的交互;多个线程并发的操作共享变量,会引发一些问题;因此需要通过同步与互斥实现一定的保护机制

1 互斥量

  互斥:同一时间理解资源的唯一访问性

  互斥锁是原子操作 

  (1)定义胡互斥锁变量:pthread_mutex_t mutex

  (2)初始化变量:pthread_mutex_init(&mutex)

  (3)临界资源加锁/解锁

    pthead_mutex_lock(&mutex)

    pthread_mutex_unlock(&mutex)

    pthread_mutex_trylock(&mutex):非阻塞

    pthread_mutex_timelock(&mutex)

  (4)销毁互斥锁:

    pthread_mutex_destory(&mutex)

2 条件变量

  当一个线程互斥的访问某个变量时,他可能发现在其他线程改变状态之前什么也做不了:例如当一个线程访问队列时,发现队列为空,它只能等待其他线程将一个节点添加到队列中,这种情况下需要条件变量

  (1)初始化

    pthread_cond_init(&cond)

  (2)销毁

    pthread_cond_destory(&cond)

  (3)等待条件满足

    pthread_cond_wait(&cond,&mutex)

    注意:为了保护条件的修改,所以我们使用了互斥锁进行保护,但是如果加锁之后条件不满足而陷入休眠,则造成死锁,因此在休眠之前先解锁,但是解锁和休眠应该是原子操作,,否则也可能会诱发死锁的情况出现

  (4)唤醒等待

    pthread_cond_signal(&cond)   只通知一个

    pthread_cond_broadcast(&cond)  唤醒所有等待的线程

3 死锁产生的必要条件

  (1)互斥条件

  (2)不可剥夺条件

  (3)请求与保持条件

  (4)环路等待条件

4 预防死锁

  破坏其中的一个条件

  银行家算法

  死锁检测算法

线程&线程控制的更多相关文章

  1. Java多线程之线程的控制

    Java多线程之线程的控制 线程中的7 种非常重要的状态:  初始New.可运行Runnable.运行Running.阻塞Blocked.锁池lock_pool.等待队列wait_pool.结束Dea ...

  2. 线程锁的本质:线程控制、线程状态控制 while if:根据线程的关系(模式)协调线程的执行

    线程锁的本质:线程控制.线程状态控制 while if https://www.cnblogs.com/feng9exe/p/8319000.html https://www.cnblogs.com/ ...

  3. java多线程中篇(三) —— 线程的控制(创建,运行,阻塞,中断,结束)

    简介 线程的控制就是程序对线程的主要管理,最重要的就是状态的切换维护. 每种转态都有不同的引发事件(对应线程的方法),每种状态又有各自不同的处理步骤和过程,整个线程控制主要就是涉及这些内容. 正文 线 ...

  4. JAVA之旅(十五)——多线程的生产者和消费者,停止线程,守护线程,线程的优先级,setPriority设置优先级,yield临时停止

    JAVA之旅(十五)--多线程的生产者和消费者,停止线程,守护线程,线程的优先级,setPriority设置优先级,yield临时停止 我们接着多线程讲 一.生产者和消费者 什么是生产者和消费者?我们 ...

  5. 常量,字段,构造方法 调试 ms 源代码 一个C#二维码图片识别的Demo 近期ASP.NET问题汇总及对应的解决办法 c# chart控件柱状图,改变柱子宽度 使用C#创建Windows服务 C#服务端判断客户端socket是否已断开的方法 线程 线程池 Task .NET 单元测试的利剑——模拟框架Moq

    常量,字段,构造方法   常量 1.什么是常量 ​ 常量是值从不变化的符号,在编译之前值就必须确定.编译后,常量值会保存到程序集元数据中.所以,常量必须是编译器识别的基元类型的常量,如:Boolean ...

  6. 线程&线程池

    线程 进程和线程: 进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程才是cpu上的执行单位. 注意:两个都是过程 线程一个特点: 一个进程中,多个线程共享资源 线程和进程区 ...

  7. Java线程 : 线程同步与锁

    一.同步问题提出 线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏. 例如:两个线程ThreadA.ThreadB都操作同一个对象Foo对象,并修改Foo对象上的数据. public ...

  8. C#线程 线程进阶

    第四部分:高级线程 非阻塞同步 前面我们说过,即使在分配或增加字段的简单情况下,也需要同步.尽管锁定始终可以满足此需求,但是竞争性锁定意味着线程必须阻塞,从而遭受上下文切换的开销和调度的延迟,这在高度 ...

  9. Linux线程的实现 & LinuxThread vs. NPTL & 用户级内核级线程 & 线程与信号处理

    另,线程的资源占用可见:http://www.cnblogs.com/charlesblc/p/6242111.html 进程 & 线程的很多知识可以看这里:http://www.cnblog ...

  10. Linux线程 之 线程 线程组 进程 轻量级进程(LWP)

    Thread Local Storage,线程本地存储,大神Ulrich Drepper有篇PDF文档是讲TLS的,我曾经努力过三次尝试搞清楚TLS的原理,均没有彻底搞清楚.这一次是第三次,我沉浸gl ...

随机推荐

  1. (14)Why some people find exercise harder than others

    https://www.ted.com/talks/emily_balcetis_why_some_people_find_exercise_harder_than_others/transcript ...

  2. boost-断言

    标准assert宏的原型声明在<assert.h>中,其作用是如果它的测试条件为假,则调用abort()终止程序执行,程序退出的时候会弹出一个错误提示框,并向控制台输出所在文件及行号.as ...

  3. L1范式和L2范式

    正则化(Regularization) 机器学习中几乎都可以看到损失函数后面会添加一个额外项,常用的额外项一般有两种,一般英文称作ℓ1ℓ1-norm和ℓ2ℓ2-norm,中文称作L1正则化和L2正则化 ...

  4. 《深入浅出MFC》系列之动态创建

    /*************************************************************************************************** ...

  5. 【应用】for:批量修改文件名

    ## @echo off setlocal EnableDelayedExpansion rem set string=suffix for %%i in (*.txt) do ( set name= ...

  6. GPT分区在IBM服务器上安装linux不能引导的解决方法

    提示: Your boot partition is on a disk using the GPT partitioning Scheme but this machines cannot boot ...

  7. kepware http接口 c语言 python

    读取某变量的值(http.client import http.client conn = http.client.HTTPConnection("127,0,0,1") head ...

  8. js-数组方法push

    <script type="text/javascript">        var arr=[1,2,3,4,5]        arr.push(6,7)      ...

  9. Java学习--基本数据类型的定义和运算

    例1: public class DataDemo05{ public static void main(String args[]){ char ch1 = '\"' ; // 表示的是一 ...

  10. iOS4.0及以上系统,关闭程序,applicationWillTerminate为调用问题解决

    iOS4.0以后系统支持多任务类型,程序按下home键后,程序进入后台运行,如果内存不足被系统关闭或者手动关闭,都不会调用applicationWillTerminate回调函数. 解决方法:可以在程 ...