---其实经过这一段时间的Linux应用编程学习,自己总结发现到,在Linux应用编程当中有四大模块我们一定要掌握(这些是最基础的东西):

  • 多进程编程
  • 多线程编程(用的比较多)
  • I/O多路复用
  • socket网络编程

而且再结合招聘平台上的要求,可以看到,要求里面大都会或多或少设计到上面中的一点。现在我们先从多线程开始学习,后面再慢慢的讲解其它模块的编程。                  其实以前在没学进程和线程之前,自己对这个充满了疑惑,上网一查,全是讲他们的区别,看了一点区别就懵圈了,因为从一开始就没弄懂进程和线程他们本质概念。现在回过头来想想也是当时,如果连这个东西叫什么东西都不知道,你就去用它其它特性,那简单是在浪费时间,做无用功。一、线程介绍:                     1、什么是线程?                     说到这个线程,那么我们先从什么是进程开始说起(这里也可以看我之前写的文章——Linux系统下进程编程(一))。在这里我想用形象的比喻给大家介绍这两个东西(当然比喻的可能不是很好,不过目的是为了理解,hh):                             想必每个人电脑上都安装了许多应用程序app吧,当你打开你的电脑时,按照你事先想好的方案(我打开电脑要做什么呢,肯定是要用到电脑上安装的app啦),我们点击桌面上的app,就会运行它了,这个时候,你可以按快捷——ctrl+shift+esc,打开Windows的任务管理器,你将会看到如下面的图片所示:

从这个图片当中我们可以看到TIM这个是我们常用的app(也就是进程),所以从中我们可以用一句简单的话来说:进程就是我们运行的程序(app)。             简单的说完了什么是进程,那么线程是啥?不知道读者有没有仔细观察,在进程下面是不是还显示了一些其他东西要运行呢,没错这个就是我们要说的线程。线程简单来说,就是在一个app(运行程序)里面干着一些细小的细活呢,没有线程的任劳任怨,进程就得不到完美解释了!

2、术语来介绍线程和进程的联系:

进程是程序执行时的一个实例,即它是程序已经执行到何种程度的数据结构的汇集。从内核的观点看,进程的目的就是担当分配系统资源(CPU时间、内存等)的基本单位。

线程是进程的一个执行流,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。一个进程可以由多个线程组成(拥有很多相对独立的执行流的用户程序共享应用程序的大部分数据结构),线程与同属一个进程的其他的线程共享进程所拥有的全部资源。

  • "进程——资源分配的最小单位,线程——程序执行的最小单位"

注意:
          进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径,所以进程挂掉了,线程就完蛋了,就比如上面的那个TIIM,你把它给关了,你就没得玩了(我看网上好多博客里面都说,一个线程死掉了,进程就死掉了,这里和我理解的有点出路,如果这里我理解错误的话,欢迎读者来讨论或者批评指正,虚心学习)。线程有自己的堆栈和局部变量,但线程没有单独的地址空间。         3、为什么还要用线程来编写程序,不是有已经进程编程了吗?               a、使用多线程的理由之一:是和进程相比,它是一种非常"节俭"的多任务操作方式。我们知道,在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段,这是一种"昂贵"的多任务工作方式。而运行于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而且,线程间彼此切换所需的时间也远远小于进程间切换所需要的时间。据统计,总的说来,一个进程的开销大约是一个线程开销的30倍左右,当然,在具体的系统上,这个数据可能会有较大的区别。                 b、使用多线程的理由之二:是线程间方便的通信机制。对不同进程来说,它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行,这种方式不仅费时,而且很不方便。线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其它线程所用,这不仅快捷,而且方便。当然,数据的共享也带来其他一些问题,有的变量不能同时被两个线程所修改,有的子程序中声明为static的数据更有可能给多线程程序带来灾难性的打击,这些正是编写多线程程序时最需要注意的地方。

经典语句:

  • fork is expensive. Memory is copied from the parent to the child, all descriptors are duplicated in the child, and so on. Current implementations use a technique called copy-on-write, which avoids a copy of the parent’s data space to the child until the child needs its own copy. But, regardless of this optimization, fork is expensive.

  • IPC is required to pass information between the parent and child after the fork. Passing information from the parent to the child before the fork is easy, since the child starts with a copy of the parent’s data space and with a copy of all the parent’s descriptors. But, returning information from the child to the parent takes more work.

  • Threads help with both problems. Threads are sometimes called lightweight processes since a thread is “lighter weight” than a process. That is, thread creation can be 10–100 times faster than process creation.

  • All threads within a process share the same global memory. This makes the sharing of information easy between the threads, but along with this simplicity comes the problem

二、线程函数介绍:

   1、线程的创建函数 (主线程用来创造子线程的):

在ubuntu中我们使用man  3    pthread_create 来查看它的用法:

 1 PTHREAD_CREATE(3)                                                                       2 Linux Programmer's Manual                                                                      3 PTHREAD_CREATE(3) 4 5 NAME 6   pthread_create - create a new thread 7 8  SYNOPSIS 9   #include 1011   int pthread_create(pthread_t *thread, const pthread_attr_t *attr,12                      void *(*start_routine) (void *), void *arg);1314   Compile and link with -pthread.

分析参数说明:

  • 第一个参数pthread_t *thread  :thread是一个指针,指向pthread_t 类型的数据 ,&thread为前面定义的一个pthread_t 类型对象的地址,以获取新建线程的标识符。

  • 第二参数const pthread_attr_t *attr:指定创建线程的属性,如线程优先级、初始栈大小、是否为守护进程等。可以使用NULL来作为默认值,通常情况下我们都是使用默认值。

  • 第三个参数void *(*start_routine) (void *):它是一个函数指针,可以联系到数组指针来看它,可以把它看成  void   *(*)(void *)    start_routine ,所以这个参数的作用是指定当新的线程创建之后,将要执行的函数。

  • 第四个参数void *arg:线程将执行的函数的参数。如果想传递多个参数,请将它们封装在一个结构体中。

  • 创建成功,返回0,失败返回error  number:

    1RETURN VALUE2      On success, pthread_create() returns 0; on error, it returns an error number, and the contents of *thread are undefined.

2、线程的合并和回收函数:

在介绍这两个函数之前,我们要明白什么是线程的合并和回收。我们在第一个函数pthread_create()负责创建了一个线程。那么线程也属于系统的资源,这跟内存没什么两样,而且线程本身也要占据一定的内存空间(只不过它是共享进程的内存)。众所周知的一个问题就是C或C++编程中如果要通过malloc()或new分配了一块内存,就必须使用free()或delete来回收这块内存,否则就会产生著名的内存泄漏问题。既然线程和内存没什么两样,那么有创建就必须得有回收,否则就会产生另外一个著名的资源泄漏问题,这同样也是一个严重的问题。那么线程的合并就是回收线程资源了(和我们之前讲解的回收僵尸进程是一个道理,不能浪费内存资源)。        线程的合并是一种主动回收线程资源的方案当一个线程调用了针对其它线程的pthread_join()接口,就是线程合并了这个接口会阻塞调用线程,直到被合并的线程结束为止。当被合并线程结束,pthread_join()接口就会回收这个线程的资源,并将这个线程的返回值返回给合并者。与线程合并相对应的另外一种线程资源回收机制是线程分离,调用接口是pthread_detach()线程分离是将线程资源的回收工作交由系统自动来完成,也就是说当被分离的线程结束之后,系统会自动回收它的资源。因为线程分离是启动系统的自动回收机制,那么程序也就无法获得被分离线程的返回值,这就使得pthread_detach()接口只要拥有一个参数就行了,那就是被分离线程句柄。         线程合并和线程分离都是用于回收线程资源的,可以根据不同的业务场景酌情使用。不管有什么理由,你都必须选择其中一种,否则就会引发资源泄漏的问题,这个问题与内存泄漏同样可怕。

下面还是老办法还是man手册来查看他们的函数原型:

  • pthread_join()函数原型:

 1  PTHREAD_JOIN(3)                                                                         2  Linux Programmer's Manual                                                                        3  PTHREAD_JOIN(3) 4 5  NAME 6       pthread_join - join with a terminated thread 7 8  SYNOPSIS 9       #include 1011       int pthread_join(pthread_t thread, void **retval);1213       Compile and link with -pthread.

分析和说明:

  • 第一个参数pthread_t thread:指定要等待的线程thread。

  • 第二个参数 void **retval  :如果不为NULL,那么线程的返回值存储在status指向的空间中(这就是为什么status是二级指针的原因!和之前介绍的输出型参数类似——c专题之指针----指针与函数传参和输入、输出型参数) 。

  • 返回值:

    1RETURN VALUE2           On success, pthread_join() returns 0; on error, it returns an error number.
  • pthread_detach()函数原型:

     1     PTHREAD_DETACH(3)                                                                       2 3 4NAME 5   pthread_detach - detach a thread 6 7SYNOPSIS 8   #include  910   int pthread_detach(pthread_t thread);1112   Compile and link with -pthread.

分析说明:

这里的参数就是传入我们之前创建成功了的线程。

  3、线程取消函数:

a、pthread_cancel(),一般都是主线程调用该函数去取消(让它赶紧死)子线程:

 1PTHREAD_CANCEL(3)                                                                       2Linux Programmer's Manual                                                                      3PTHREAD_CANCEL(3) 4 5NAME 6   pthread_cancel - send a cancellation request to a thread 7 8SYNOPSIS 9   #include 1011   int pthread_cancel(pthread_t thread);1213   Compile and link with -pthread.

分析说明:

这个函数唯一的参数就是我们要终止的线程的标识符thread。

b、pthread_exit()函数:

 1PTHREAD_EXIT(3)                                                                         2Linux Programmer's Manual                                                                        3PTHREAD_EXIT(3) 4 5NAME 6   pthread_exit - terminate calling thread 7 8SYNOPSIS 9   #include 1011   void pthread_exit(void *retval);1213   Compile and link with -pthread.

分析说明:

这个函数的作用是,终止调用它的线程。函数参数是函数返回时的代码。注意一点的是这函数必须在pthread_join()函数第二个参数不为NULL的前提下才能够执行 ----------------这个pthread_exit()函数写在被调用子线程中

    4、获取线程ID函数(这个函数使用比较简单):

 1NAME 2   pthread_self - obtain ID of the calling thread 3 SYNOPSIS 4   #include  5 6   pthread_t  pthread_self(void); 7 8 Compile and link with -pthread. 910DESCRIPTION11   The pthread_self() function returns the ID of the calling thread.  This is the same value that is returned in *thread in the pthread_create(3) call that created this thread.1213RETURN VALUE14   This function always succeeds, returning the calling thread's ID.

三、总结:

今天主要是简单的介绍了一下线程的概念和一些基本函数使用,当然还有一些函数没介绍完(比如属性函数,这里就先不介绍了,在后面的实战当中如有要使用,我们再来介绍也不迟,先把今天介绍的几个函数吸收掉,好方便后面的学习)。好的,今天的分享就到这里,明天继续分享线程的系列文章实战篇。


---欢迎关注公众号,可以查看往期的文章,可以得到三本经典的c语言进阶电子书:

Linux爱好者(对文章中写有不对的地方,可以批评指出,虚您学习,大家一起进步。加个人微信,技术等话题,群里只能讨论技术,发广告,立刻飞机):

linux 线程_Linux线程编程专题之线程和线程函数介绍相关推荐

  1. linux 线程_Linux 多线程编程(不限Linux)

    前言 线程?为什么有了进程还需要线程呢,他们有什么区别?使用线程有什么优势呢?还有多线程编程的一些细节问题,如线程之间怎样同步.互斥,这些东西将在本文中介绍.我在某QQ群里见到这样一道面试题: 是否熟 ...

  2. linux内核_Linux驱动编程的本质就是Linux内核编程

    由于Linux驱动编程的本质属于Linux内核编程,因此我们非常有必要熟悉Linux内核以及Linux内核的特点. 这篇文章将会帮助读者打下Linux驱动编程的基础知识. 本篇文章分为如下三个小节进行 ...

  3. linux内核_Linux内核编程风格简介

    01不同的语言风格 当今世界上一共有5000多种语言.不同的国家.民族和地区,说着不同的语言.每个民族不一定有自己的文字,但一般都会有自己的语言.即使是同一种语言,在不同的时代.不同的地区和群体,说话 ...

  4. 1.socket编程:socket编程,网络字节序,函数介绍,IP地址转换函数,sockaddr数据结构,网络套接字函数,socket相关函数,TCP server和client

     1  Socket编程 socket这个词可以表示很多概念: 在TCP/IP协议中,"IP地址+TCP或UDP端口号"唯一标识网络通讯中的一个进程,"IP 地址+端 ...

  5. int linux 原子操作_linux c++编程之多线程:原子操作如何解决线程冲突

    在多线程中操作全局变量一般都会引起线程冲突,为了解决线程冲突,引入原子操作. 1.线程冲突 #include #include #include #include int g_count = 0;vo ...

  6. Linux学习之系统编程篇:杀死 / 取消线程

    函数: int pthread_cancel(pthread_t thread);//参数:线程 ID 注意:并不是调用了 pthread_cancel,就一定能杀死进程, 必须死在"取消点 ...

  7. Linux学习之系统编程篇:回收子线程资源

    子线程退出后,主控线程也是需要回收子线程资源的. 函数:pthread_ join 阻塞等待线程退出,获取线程退出状态函数说明: int pthread_join(pthread_t thread, ...

  8. Linux学习之系统编程篇:练习验证线程共享全局变量

    #include <pthread.h> #include <stdio.h> #include <unistd.h> int var = 1001; void * ...

  9. Linux多线程服务端编程笔记,陈硕Linux多线程服务端编程读书笔记 —— 第一章 线程安全的对象生命周期管理...

    muduo书第一章的思维导图(新窗口打开可以看大图) 线程安全的对象析构和回调(使用shared_ptr和weak_ptr) 注释是英文的(工地英语-) StockFactory.h // in mu ...

  10. Linux下的C编程实战(开发平台搭建,文件系统编程,进程控制与进程通信编程,“线程”控制与“线程”通信编程,驱动程序设计,专家问答)

    Linux下的C编程实战(一) ――开发平台搭建 1.引言 Linux操作系统在服务器领域的应用和普及已经有较长的历史,这源于它的开源特点以及其超越Windows的安全性和稳定性.而近年来,Linux ...

最新文章

  1. 微软私有云Azure Pack实践系列之三创建虚拟机角色
  2. python 字符串补齐
  3. java 获取文件权限_Java中的文件权限,检查权限和更改权限 - Break易站
  4. WebAssembly + Dapr = 下一代云原生运行时?
  5. 【译】Private AI — Federated Learning with PySyft and PyTorch
  6. Nginx与Tomcat区别
  7. 【Linux】一步一步学Linux——egrep命令(50)
  8. python安装多久_python安装与使用
  9. Git笔记(10) 别名
  10. julia有 pytorch包吗_PyTorch 有哪些坑/bug?
  11. l298n使能端跳线帽_L298N 驱动模块的应用
  12. log4j错误log4j:WARN No appenders could be found for logger
  13. 浏览器下载ftp文件
  14. linux命令join的用法,linux join命令
  15. MyEclipse:详细使用教程
  16. 经络是怎样分类命名的?十二经脉的分布和循行
  17. 91-Lucene+ElasticSeach核心技术
  18. 湖南大学夏令营c语言考试题,夏令营试题
  19. VC++6.0 win32 控制台应用程序 简单应用 附代码
  20. 1+X 云计算运维与开发(中级)案例实战——搭建harbor私有仓库并实现主从同步

热门文章

  1. 在sqlyog进行数据库的备份_狂神说MySQL07:权限及如何设计数据库
  2. AccessibilityService的具体应用场景
  3. html 怎么把表格不给输入,如何让用户在HTML5网页表单中输入持续时间而不会让他们烦恼?...
  4. wpf label字体为斜体_快来收下这份字体设计必备知识点
  5. 云数据库mysql 慢查询_Mysql慢查询
  6. java 字符字节数组_Java字符串与字符、字节数组知识点总结
  7. win10 mysql5.7.21_win10下mysql5.7.21解压版安装教程
  8. ibm linux mq 发送消息_IBM MQ简明教程——2. 将消息发送至远程队列
  9. Hands-on Lab (9) - 增加用户
  10. Vue 3 最新进展