线程概念

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

线程与进程比较

①  和进程相比,它是一种非常“节俭”的多任务操作方式。在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()所指定的清理函数。

实验1

功能:使用pthread_create()函数创建线程的实例

代码:thread_create.c文件

编译:使用命令:gcc thread_create.c -o thread_create -lpthread编译,注意不要忘了加 -lpthread,否则会出现如下的错误

/tmp/ccjfZIN3.o: In function `main':
thread_create.c:(.text+0x8b): undefined reference to `pthread_create'
thread_create.c:(.text+0xc0): undefined reference to `pthread_create'
thread_create.c:(.text+0xeb): undefined reference to `pthread_join'
thread_create.c:(.text+0xfc): undefined reference to `pthread_join'
collect2: ld returned 1 exit status

执行:

实验2

功能:使用pthread_exit()函数退出线程的举例

  代码:thread_exit.c文件

  编译:gcc thread_exit.c -o thread_exit -lpthread

执行:./thread_exit

实验3

功能:用pthread_join()实现线程等待。

  代码:thread_join.c文件

  编译:gcc thread_join.c -o thread_join -lpthread

执行:./thread_join

可以看出,pthread_join()等到线程结束后,程序才继续执行。

实验4

功能:使用pthread_self()获取线程ID

  代码:thread_id.c文件

  编译:gcc thread_id.c -o thread_id -lpthread

  执行:./thread_id

实验5

  功能:线程清理函数的使用

代码:thread_clean.c

注意,在编写的代码的时候,自己修改一下传递的参数和clean_pop函数的参数,相信你会更有收获。

编译:gcc thread_clean.c -o thread_clean -lpthread

  执行:./thread_clean

实验6

功能:本实验创建了3个进程,为了更好的描述线程之间的并行执行,让3个线程共用同一个执行函数。每个线程都有5次循环(可以看成5个小任务),每次循环之间会随机等待1~10s的时间,意义在于模拟每个任务的到达时间是随机的,并没有任何特定的规律。

  代码:thread.c文件,该代码文件点此下载

  编译:gcc thread.c -o thread -lpthread

  执行:./thread

从实验结果可以看出,线程执行的顺序杂乱无章的,看着就头疼,下一节就利用线程之间的同步与互斥机制处理此文件http://blog.csdn.net/mybelief321/article/details/9390707

Linux多线程编程(一)---多线程基本编程的更多相关文章

  1. linux下C语言多线程编程实例

    用一个实例.来学习linux下C语言多线程编程实例. 代码目的:通过创建两个线程来实现对一个数的递加.代码: //包含的头文件 #include <pthread.h> #include ...

  2. linux下C++的多线程编程

    1. 引言 线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去,是在80年代中期,solaris是这方面的佼佼者.传统的Unix也支持线程的概念,但是在一个进程(proces ...

  3. Python之旅:并发编程之多线程理论部分

    一 什么是线程 在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程 线程顾名思义,就是一条流水线工作的过程,一条流水线必须属于一个车间,一个车间的工作过程是一个进程 车间负责把资源整合 ...

  4. 29 python 并发编程之多线程理论

    一 什么是线程 在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程 线程顾名思义,就是一条流水线工作的过程,一条流水线必须属于一个车间,一个车间的工作过程是一个进程 车间负责把资源整合 ...

  5. 三 python并发编程之多线程-理论

    一 什么是线程 在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程 线程顾名思义,就是一条流水线工作的过程,一条流水线必须属于一个车间,一个车间的工作过程是一个进程 车间负责把资源整合 ...

  6. TCP/IP网络编程之多线程服务端的实现(二)

    线程存在的问题和临界区 上一章TCP/IP网络编程之多线程服务端的实现(一)的thread4.c中,我们发现多线程对同一变量进行加减,最后的结果居然不是我们预料之内的.其实,如果多执行几次程序,会发现 ...

  7. python并发编程之多线程理论部分

    阅读目录 一 什么是线程 二 线程的创建开销小 三 线程与进程的区别 四 为何要用多线程 五 多线程的应用举例 六 经典的线程模型(了解) 七 POSIX线程(了解) 八 在用户空间实现的线程(了解) ...

  8. 网络编程之多线程——GIL全局解释器锁

    网络编程之多线程--GIL全局解释器锁 一.引子 定义: In CPython, the global interpreter lock, or GIL, is a mutex that preven ...

  9. 第十篇.3、ython并发编程之多线程理论部分

    一 什么是线程 在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程 线程顾名思义,就是一条流水线工作的过程,一条流水线必须属于一个车间,一个车间的工作过程是一个进程 车间负责把资源整合 ...

随机推荐

  1. JQuery中回车键登陆

    //点击回车键 //王东升/2015/3/11 document.onkeydown = function (event) { var e = event ? event : (window.even ...

  2. eclipse手动添加源码

    在开发过程中,有的时候需要我们自已手动去添加一些源码文件,但是由于我们可能在eclipse中安装了jad反编译插件,我们再用“Ctrl + 鼠标左键”的话,会打开已经反编译好的class文件,而不是带 ...

  3. 10247 - Complete Tree Labeling(递推高精度)

    Problem B Complete Tree Labeling! Input: standard input Output: standard output Time Limit: 45 secon ...

  4. Bandwidthd+Postgresql数据库配置笔记

    Bandwidthd+Postgresql数据库配置笔记 本系列文章由ex_net(张建波)编写,转载请注明出处. http://blog.csdn.net/zjianbo/article/detai ...

  5. Tomcat 中会话超时的相关配置

      QC同事提到似乎有时Tomcat的会话超时表现有问题,记录一下可能用到的配置. 1)超时时间的设定       tomcat的会话超时可以在多个级别上设置:tomcat实例级别.Web应用级别.s ...

  6. 用于COB工艺的PCB设计指导

    绑定角度尽量在45°之内,多于这个角度,绑定时候,银线不好打入焊盘.而且打入焊盘的尾部可能短路到相邻的焊盘,绑定焊盘之间的间距一般在4MIL为极限,半场的工艺一般就这样了.而且焊盘离被绑定的IC引脚最 ...

  7. Json.Net系列教程 3.Json.Net序列化和反序列化设置

    原文 Json.Net系列教程 3.Json.Net序列化和反序列化设置 上节补充 首先补充一点,Json.Net是支持序列化和反序列化DataTable,DataSet,Entity Framewo ...

  8. 宣布正式发布 Windows Azure 多重身份验证

    身份和访问管理是安全之锚,是企业 IT 部门的首要任务.它是随时随地向员工.合作伙伴和客户提供访问的关键所在.今天,我们非常高兴地宣布正式发布 Windows Azure 多重身份验证,从而为 IT ...

  9. 把一个数组向右循环移动k位要求时间复杂度为O(n)

    今晚做了下某公司的网络笔试题,好久没刷题了,现在渣得要死,里面有道程序设计题是 把一个数组向右循环移动k位要求时间复杂度为O(n) 给的方法定义为 public void solution(int a ...

  10. c 输出9x9乘法口诀表 这个学for循环绕不开的一题

    #include<stdio.h> int main(void) { int i,j; ;i<=;i++) { ;j<=i;j++) { printf("%d*%d= ...