Linux多线程编程

线程概念

线程是指运行中的程序的调度单位。一个线程指的是进程中一个单一顺序的控制流,也被称为轻量级线程。它是系统独立调度和分配的基本单位。同一进程中的多个线程将共享该系统中的全部系统资源,比如文件描述符和信号处理等。一个进程可以有很多线程,每个线程并行执行不同的任务。

线程与进程比较

① 和进程相比,它是一种非常“节俭”的多任务操作方式。在Linux系统中,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护其代码段、堆栈段和数据段,这种多任务工作方式的代价非常“昂贵”。而运行于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而且线程间彼此切换所需要时间也远远小于进程间切换所需要的时间。

② 线程间方便的通信机制。对不同进程来说它们具有独立的数据空间,要进行数据的传递只能通过通信的方式进行。这种方式不仅费时,而且很不方便。线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可以直接为其他线程所用,不仅方便,而且快捷。

线程基本编程

Linux系统下的多线程遵循POSIX线程接口,称为pthread。编写Linux下的多线程程序,需要使用头文件pthread.h,连接时需要使用库libpthread.a。因为pthread的库不是Linux系统的库,所以在编译时要加上 -lpthread。例如:gcc filename -lpthread。注意,这里要讲的线程相关操作都是用户空间中的线程的操作。

线程创建:创建线程实际上就是确定调用该线程函数的入口点,这里通常使用的函数是pthread_create()。在线程创建后,就开始运行相关的线程函数。

线程退出:在线程创建后,就开始运行相关的线程函数,在该函数运行完之后,该线程也就退出了,这也是线程退出的一种方法。另一种退出线程的方法是使用函数pthread_exit(),这是线程的主动行为。这里要注意的是,在使用线程函数时,不能随意使用exit()退出函数来进行出错处理。由于exit()的作用是使调用进程终止,而一个进程往往包含多个线程,因此,在使用exit()之后,该进程中的所有线程都终止了。在线程中就可以使用pthread_exit()来代替进程中的exit()。

线程等待:由于一个进程中的多个线程是共享数据段的,因此,通常在线程退出后,退出线程所占用的资源并不会随着线程的终止而得到释放。正如进程之间可以用wait()系统调用来同步终止并释放资源一样,线程之间也有类似机制,那就是pthread_join()函数。pthread_join()用于将当前进程挂起来等待线程的结束。这个函数是一个线程阻塞的函数,调用它的函数将一直等待到被等待的线程结束为止,当函数返回时,被等待线程的资源就被收回。

线程取消:前面已经提到线程调用pthread_exit()函数主动终止自身线程,但是在很多线程应用中,经常会遇到在别的线程中要终止另一个线程的问题,此时调用pthread_cancel()函数来实现这种功能,但在被取消的线程的内部需要调用pthread_setcancel()函数和pthread_setcanceltype()函数设置自己的取消状态。例如,被取消的线程接收到另一个线程的取消请求之后,是接受函数忽略这个请求;如果是接受,则再判断立刻采取终止操作还是等待某个函数的调用等。

线程标识符获取:获取调用线程的标识ID。

线程清除:线程终止有两种情况:正常终止和非正常终止。线程主动调用pthread_exit()或者从线程函数中return都将使线程正常退出,这是可预见的退出方式;非正常终止是线程在其它线程的干预下,或者由于自身运行出错(比如访问非法地址)而退出,这种退出方式是不可预见的。不论是可预见的线程终止还是异常终止,都回存在资源释放的问题,如何保证线程终止时能顺利地释放掉自己所占用的资源,是一个必须考虑的问题。

从pthread_cleanup_push()的调用点到pthread_cleanup_pop()之间的程序段中的终止动作(包括调用pthread_exit()和异常终止,不包括return)都将执行pthread_cleanup_push()所指定的清理函数。

Linuxc/c++服务器开发高阶视频学习资料+qun720209036获取

更多视频内容包括C/C++,Linux,Nginx,ZeroMQ,MySQL,Redis,MongoDB,ZK,流媒体,P2P,K8S,Docker,TCP/IP,协程,DPDK多个高级知识点分享。

视频链接:C/C++Linux服务器开发/后台架构师-学习视频

1、如何利用2个条件变量实现线程同步?

思路:就是来回的利用pthread_cond_signal()函数,当一方被阻塞时,唤醒函数可以唤醒pthread_cond_wait()函数,只不过pthread_cond_wait()这个方法要执行其后的语句,必须遇到下一个阻塞(也就是pthread_cond_wait()方法时),才执行唤醒后的其后语句。

代码如下:


#include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<string.h>#include<pthread.h>#define MAX_NUM 2static int count = 1;pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t js = PTHREAD_COND_INITIALIZER;pthread_cond_t os = PTHREAD_COND_INITIALIZER;void* A(void *arg){pthread_mutex_lock(&mutex);while(count <= MAX_NUM){if(count%2 == 1){printf("A = %d\n", count);count++;pthread_cond_signal(&os);sleep(5);printf("bbbbbbbbbbbbbbbbbbbbbbbbbbb\n");}else{printf("ccccccccccccccccccccccccccc\n");pthread_cond_wait(&js, &mutex);printf("ddddddddddddddddddddddddddd\n");}pthread_mutex_unlock(&mutex);}}void* B(void *arg){pthread_mutex_lock(&mutex);while(count <= MAX_NUM){if(count%2 == 0){printf("B = %d\n", count);count++;pthread_cond_signal(&js);}else{pthread_cond_wait(&os, &mutex);printf("aaaaaaaaaaaaaaaaaaaaaaaaaaaa\n");}}pthread_mutex_unlock(&mutex);}int main(void){pthread_t tid1, tid2;pthread_create(&tid2, NULL, B, NULL);sleep(1);pthread_create(&tid1, NULL, A, NULL);pthread_join(tid1, NULL);pthread_join(tid2, NULL);return 0;}

运行结果

上面的这个程序就是:2个条件变量对一个互斥量的操作。signal()发送唤醒wait(),wait()之后的语句暂时不执行,直到下一次遇到wait()时,阻塞,返回执行唤醒的wait()之后的语句。

2、怎么创建10个线程的开始运行和结束过程?

利用2个条件变量和1个互斥量即可实现。

代码如下:

#include<stdio.h>#include<unistd.h>#include<stdlib.h>#include<string.h>#include<pthread.h>pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t cond = PTHREAD_COND_INITIALIZER;pthread_cond_t cond1 = PTHREAD_COND_INITIALIZER;void* thread_fun1(void *arg){int i = *(int *)arg;pthread_mutex_lock(&mutex);printf("[%d] thread start up\n", i);pthread_cond_wait(&cond, &mutex);printf("[%d]thread is wake up\n", i);pthread_mutex_unlock(&mutex);}void* thread_fun2(void *arg){pthread_cond_broadcast(&cond); //广播,一次唤醒所有的线程}int main(void){pthread_t tid1[10], tid2;int i;for(i = 0; i < 10; i++){pthread_create(&tid1[i], NULL, thread_fun1, &i);//创建10个线程sleep(1);}pthread_create(&tid2, NULL, thread_fun2, NULL);//创建1个线程for(i = 0; i < 10; i++){ //主线程等子线程执行完pthread_join(tid1[i], NULL);}pthread_join(tid2, NULL);return 0;}

运行结果

多线程的编程中:互斥量、条件变量是重中之重!!!

c/c++ Linux多线程编程相关推荐

  1. ZT 为什么pthread_cond_t要和pthread_mutex_t同时使用 || pthread/Linux多线程编程

    为什么线程同步的时候pthread_cond_t要和pthread_mutex_t同时使用 (2009-10-27 11:07:23) 转载▼ 标签: 杂谈 分类: 计算机 举一个例子(http:// ...

  2. linux查询某域线程是否满了,Linux多线程编程的时候怎么查看一个进程中的某个线程是否存活...

    pthread_kill: 别被名字吓到,pthread_kill可不是kill,而是向线程发送signal.还记得signal吗,大部分signal的默认动作是终止进程的运行,所以,我们才要用sig ...

  3. linux线程 ppt,Linux多线程编程多核编程.ppt

    <Linux多线程编程多核编程.ppt>由会员分享,可在线阅读,更多相关<Linux多线程编程多核编程.ppt(28页珍藏版)>请在装配图网上搜索. 1.Linux多线程编程, ...

  4. 多核程序设计 linux,多核程序设计Linux多线程编程.ppt

    Linux多线程编程,IEEE POSIX 标准 p1003.1c (Pthreads) 定义了处理线程的一系列C 语言类型的API. 在Linux中,线程一般被认为是"轻量级的进程&quo ...

  5. Linux 多线程编程(实现生产者消费者模型)

    Linux 多线程编程 线程分类 线程按照其调度者可以分为用户级线程和内核级线程两种. 内核级线程 在一个系统上实现线程模型的方式有好几种,因内核和用户空间提供的支持而有一定程度的级别差异.最简单的模 ...

  6. Linux多线程编程---线程间同步(互斥锁、条件变量、信号量和读写锁)

    本篇博文转自http://zhangxiaoya.github.io/2015/05/15/multi-thread-of-c-program-language-on-linux/ Linux下提供了 ...

  7. Linux多线程编程-互斥锁

    互斥锁 多线程编程中,(多线程编程)可以用互斥锁(也称互斥量)可以用来保护关键代码段,以确保其独占式的访问,这有点像二进制信号量.POSIX互斥锁相关函数主要有以下5个: #include <p ...

  8. Linux 多线程编程

    这篇文章总结下 Linux 中多线程编程中能用到的几个函数,当然,需要同步操作的时候还需要加锁的操作,这里,没有列举的这么具体,只是把最常用的函数介绍下. 在编写多线程程序在编译的时候需要加上 -lp ...

  9. 详解Linux多线程编程

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

最新文章

  1. 对 makefile 中 .SECONDARY 的学习体会
  2. java如何將數組反轉_Java基礎練習題 (4)數組操作
  3. [驱动注册]platform_driver_register()与platform_device_register()
  4. pyspark union代码示例
  5. 获取jpg图片的x,y的分辨率dpi
  6. Java任务调度之Quartz快速入门
  7. (2)vue.js介绍
  8. qt调用外部程序(exe)
  9. 基于winpcap的网络数据包的捕获与分析
  10. 谷歌开放语音识别 API,发力人工智能
  11. 首席架构师眼里的架构本质
  12. 什么是静态网页 什么是HTML5,什么是静态网页?
  13. 根据CTP接口计算现手、增仓、开平、对手盘 (1)
  14. 新兴的计算机设备,澳洲新兴专业-计算机数控,你会心动吗?
  15. MathJax 支持的 Latex 符号总结
  16. 那些年,Linus torvalds大神喷过的技术
  17. 苦禅箜mm让我帮她做的作业
  18. 大汉诡辩达人陆贾的公关策略cathy荷塘月色新浪博客
  19. 多用途互联网邮件扩展--MIME类型简介
  20. 到底无支付牌照的电商公司能开展什么样的业务!!

热门文章

  1. mac连接华为手机调试android程序
  2. AutoCAD、3D-Tool与电子相关的使用
  3. 剑指 Offer 52. 两个链表的第一个公共节点
  4. 【专升本计算机】甘肃省2020年专升本计算机测试题
  5. [转]C++中const、volatile、mutable的用法
  6. C++网络安全入侵检测技术模块及源程序代码
  7. 全民直播答题,让你离智障越来越近
  8. LeetCode28-实现strStr()(水题)
  9. GNU makefile 学习 - ongoing
  10. U盘加密软件测试简历,信息安全深透测试与工房(三)持久加密U盘版KALI