转行程序员浅谈 Linux 下的多线程编程

用户头像
WB
关注
发布于: 2020 年 05 月 24 日
转行程序员浅谈Linux下的多线程编程

[TOC]



多线程编程作为程序员无法绕过去的一个话题,同时也是面试必考题目,是每个程序员必会的基本技能之一。



由于工作后基本每天都是写业务代码,我很少涉及到多线程编程。虽说之前学过相关知识,但没有实战经验,导致我对多线程的理解一直处于学习和遗忘的循环之中。



这不最近接手了以太网应用层协议栈的维护和开发,才得以有机会接触到多线程的相关技术。因此,我花了一个星期的时间对着项目代码和书本一点点啃多线程编程及其相关技术。



通过一周的学习,我算是基本掌握了多线程编程,今天写文章做个总结。



什么是多线程



线程作为操作系统中最小的调度实体,它能够提高应用程序在多核CPU环境下的运行速度。每个进程都能运行多个线程,这些同一进程下的多个线程将共享该进程的全部资源,但不同线程有自己的调用栈、寄存器环境和线程本地存贮。在linux系统下,进程中包含诸多资源,在多数场景下,需要不同函数间交换数据,共同完成某个功能。



如果采用多进程通信,则进程间通信将占据大量系统资源,开销巨大。如果采用多线程通信,由于进程的诸多资源对于线程来说是共享的,因此多线程通信对于资源消耗少,通信效率高。



因此,多线程编程中的重点集中于线程对于进程中共享资源的访问,如果处理不好多个线程访问公共资源的问题,则应用程序就有可能发生崩溃,导致软件运行异常。



多线程编程的基本步骤



多线程编程分为以下几个步骤:

  • 线程资源的定义和声明

  • 互斥锁、条件变量、事件的初始化和属性设置

  • 线程创建线程函数运行线程结束运行,资源回收



多线程编程的重点是:线程的同步与互斥根据业务或者功能,将子线程的处理逻辑用代码实现



Note:由于多线程编程的流程和API均一致,因此文章不在附上代码。如有疑问,请上网搜索代码实现。



线程同步

线程同步是多线程编程中无法绕开的一个话题,由于多线程是在一个进程内运行,因此很多公共资源需要各线程共享使用。



当多个线程同时访问某个公共资源时,操作系统如何处理多个线程的访问请求,这就涉及到多线程同步的知识了。如果线程之间不采用同步机制,导致多个线程同时访问某资源,则可能会使得程序挂掉。



最常用的三种线程同步机制:

(1)互斥锁同步:互斥锁同步常用于多线程对于共享变量的操作,为了避免多个线程同时操作共享变量,需要在操作共享变量前将互斥锁lock,阻止其他线程访问该变量。当对该变量操作完毕后,将互斥锁unlock,此时其他线程能够操作该变量。

互斥锁的使用分为以下几个步骤:

//互斥锁声明
pthread_mutex_t mutex;
//互斥锁初始化
pthread_mutex_init(&mutex);
//互斥锁lock
pthread_mutex_lock(&mutex);
//操作公共资源
//互斥锁unlock
pthread_mutex_unlock(&mutex);



(2)条件变量同步:条件变量常用于线程同步,一个线程处于等待某条件就绪,直到另一个线程将条件满足的信号发往该线程,则该线程结束阻塞状态。条件变量常与互斥锁同时使用。



当线程A运行到pthreadcondwait()函数时,线程A因为条件不满足而处于阻塞状态。当线程B运行到pthread_condsignal()时,该条件被满足,此时线程A才会结束阻塞状态,继续运行。



程序员不需要关心条件何时满足或不满足,这全部由操作系统内核完成。我们只需要知道当线程运行到pthreadcondwait()时,线程会阻塞。当另一个线程运行到ptread_condsignal(),阻塞的线程恢复即可。



pthread_mutex_lock(&mutex);
pthread_cond_wait(); //线程阻塞,等待条件满足
pthread_mutex_unlock(&mutex);
pthread_mutex_lock(&mutex);
pthread_condsingal(); //条件满足,通知等待线程继续运行
pthread_mutex_lock(&mutex);

(3)事件通知同步:事件通知同步机制并不是书本中介绍的知识,而是我在阅读项目源码学到的一种线程同步机制,我觉得是一种很好的线程同步方法。



该机制利用eventfd()和poll()函数来实现线程的同步,严格来说这是属于linux的文件I/O部分的知识点,但是多线程中使用事件同步机制也是非常广泛的。



关于多线程的事件同步机制,我打算单独写一篇文章来介绍,这里就不再过多赘述了。

总结



这篇文章简单介绍了多线程的概念,多线程编程的流程以及多线程的三种同步机制。文章中的知识点都比较基础,主要面向初学者,对于有经验的程序员来说毫无意义。



当然,我这篇文章并不能让你学会多线程编程,但从概念—流程—同步的这个学习步骤是可以借鉴的。如果你想彻底明白多线程编程,我的经验是:

  • 对计算机操作系统有基本了解

  • 了解线程和进程的概念

  • 看代码中别人如何进行多线程编程

  • 亲手用代码实现



我推荐的学习资料:

  • 《计算机操作系统》汤子瀛版

  • 极客时间《趣谈linux操作系统》课程

  • 《嵌入式Linux应用程序开发标准教程(第二版)》



ps: 欢迎关注我的公众号[酷酷的coder],分享转行菜鸟程序员成长过程汇总的烦恼和反思.

发布于: 2020 年 05 月 24 日 阅读数: 35
用户头像

WB

关注

车联网,AutoSar,功能安全,Linux 2018.12.15 加入

还未添加个人简介

评论

发布
暂无评论
转行程序员浅谈Linux下的多线程编程