1. Linux多线程概述

1.1. 概述

进程是系统中程序执行和资源分配的基本单位。每个进程有自己的数据段、代码段和堆栈段。这就造成进程在进行切换等操作时都需要有比较负责的上下文切换等动作。为了进一步减少处理器的空转时间支持多处理器和减少上下文切换开销,也就出现了线程。

线程通常叫做轻量级进程。线程是在共享内存空间中并发执行的多道执行路径,是一个更加接近于执行体的概念,拥有独立的执行序列,是进程的基本调度单元,每个进程至少都有一个main线程。它与同进程中的其他线程共享进程空间{堆 代码 数据 文件描述符 信号等},只拥有自己的栈空间,大大减少了上下文切换的开销。

线程和进程在使用上各有优缺点:线程执行开销小,占用的CPU少,线程之间的切换快,但不利于资源的管理和保护;而进程正相反。从可移植性来讲,多进程的可移植性要好些。

同进程一样,线程也将相关的变量值放在线程控制表内。一个进程可以有多个线程,也就是有多个线程控制表及堆栈寄存器,但却共享一个用户地址空间。要注意的是,由于线程共享了进程的资源和地址空间,因此,任何线程对系统资源的操作都会给其他线程带来影响。

1.2. 线程分类

按调度者分为用户级线程和核心级线程

·用户级线程:主要解决上下文切换问题,调度算法和调度过程全部由用户决定,在运行时不需要特定的内核支持。缺点是无法发挥多处理器的优势

·核心级线程:允许不同进程中的线程按照同一相对优先调度方法调度,发挥多处理器的并发优势

现在大多数系统都采用用户级线程和核心级线程并存的方法。一个用户级线程可以对应一个或多个核心级线程,也就是“一对一”或“一对多”模型。

1.3. 线程创建的Linux实现

Linux的线程是通过用户级的函数库实现的,一般采用pthread线程库实现线程的访问和控制。它用第3方posix标准的pthread,具有良好的可移植性。 编译的时候要在后面加上 –lpthread

创建 退出 等待

多进程 fork() exit() wait()

多线程 pthread_create pthread_exit() pthread_join()

2. 线程的创建和退出

创建线程实际上就是确定调用该线程函数的入口点,线程的创建采用函数pthread_create。在线程创建以后,就开始运行相关的线程函数,在该函数运行完之后,线程就退出,这也是线程退出的一种方式。另一种线程退出的方式是使用函数pthread_exit()函数,这是线程主动退出行为。这里要注意的是,在使用线程函数时,不能随意使用exit退出函数进行出错处理,由于exit的作用是使调用进程终止,往往一个进程包括了多个线程,所以在线程中通常使用pthread_exit函数来代替进程中的退出函数exit。

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

函数原型:

#include <pthread.h>

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

void pthread_exit(void *retval);

通常的形式为:

pthread_t pthid;

pthread_create(&pthid,NULL,pthfunc,NULL);或pthread_create(&pthid,NULL,pthfunc,(void*)3);

pthread_exit(NULL);或pthread_exit((void*)3);//3作为返回值被pthread_join函数捕获。

函数pthread_create用来创建线程。返回值:成功,则返回0;失败,则返回-1。各参数描述如下:

·参数thread是传出参数,保存新线程的标识;

·参数attr是一个结构体指针,结构中的元素分别指定新线程的运行属性,attr可以用pthread_attr_init等函数设置各成员的值,但通常传入为NULL 即可;

·参数start_routine是一个函数指针,指向新线程的入口点函数,线程入口点函数带有一个void *的参数由pthread_create的第4个参数传入;

·参数arg用于传递给第3个参数指向的入口点函数的参数,可以为NULL,表示不传递。

函数pthread_exit表示线程的退出。其参数可以被其它线程用pthread_join函数捕获。

示例:

#include <stdio.h>

#include <pthread.h>

void *ThreadFunc(void *pArg) //参数的值为123

{

int i = 0;

for(; i<10; i++)

{

printf("Hi,I'm child thread,arg is:%d\n", (int)pArg);

sleep(1);

}

pthread_exit(NULL);

}

int main()

{

pthread_t thdId;

pthread_create(&thdId, NULL, ThreadFunc, (void *)123 );

int i = 0;

for(; i<10; i++)

{

printf("Hi,I'm main thread,child thread id is:%x\n", thdId);

sleep(1);

}

return 0;

}

编译时需要带上线程库选项:

gcc -o a a.c -lpthread

LINUX多线程(一)(创建和退出)的更多相关文章

  1. C++ Linux 多线程之创建、管理线程

    线程就是,在同一程序同一时间内同意运行不同函数的离散处理队列. 这使得一个长时间去进行某种特殊运算的函数在运行时不阻碍其它的函数变得十分重要. 线程实际上同意同一时候运行两种函数,而这两个函数不必相互 ...

  2. Linux 多线程编程--线程退出

    今天分析项目中进程中虚存一直增长问题,运行10个小时虚存涨到121G ,RSS占用为16G 非常恐怖. Valgrind测试无内存泄漏. 内存32G 64bit系统信息如下: Linux线程使用方式是 ...

  3. Linux 多线程应用中如何编写安全的信号处理函数

    http://blog.163.com/he_junwei/blog/static/1979376462014021105242552/ http://www.ibm.com/developerwor ...

  4. Linux多线程——使用互斥量同步线程

    前文再续,书接上一回,在上一篇文章: Linux多线程——使用信号量同步线程中,我们留下了一个如何使用互斥量来进行线程同步的问题,本文将会给出互斥量的详细解说,并用一个互斥量解决上一篇文章中,要使用两 ...

  5. Python多线程的创建,相关函数和守护线程的理解

    一:多线程的创建 threading库创建线程有两种方式,函数式和继承式    1)函数式 def func(): print 'Starting' print 'Ending' t=threadin ...

  6. 笔记整理--Linux多线程

    Unix高级环境编程系列笔记 (2013/11/17 14:26:38) Unix高级环境编程系列笔记 出处信息 通过这篇文字,您将能够解答如下问题: 如何来标识一个线程? 如何创建一个新线程? 如何 ...

  7. Linux多线程编程初探

    Linux线程介绍 进程与线程 典型的UNIX/Linux进程可以看成只有一个控制线程:一个进程在同一时刻只做一件事情.有了多个控制线程后,在程序设计时可以把进程设计成在同一时刻做不止一件事,每个线程 ...

  8. POSIX 线程的创建与退出

    前言 创建线程: pthread_create() 退出线程: pthread_exit()return pthread_cancel() 线程的创建 使用多线程,首先就需要创建一个新线程.那么线程是 ...

  9. Linux多线程--使用互斥量同步线程【转】

    本文转载自:http://blog.csdn.net/ljianhui/article/details/10875883 前文再续,书接上一回,在上一篇文章:Linux多线程——使用信号量同步线程中, ...

随机推荐

  1. Binary Tree 分类: POJ 2015-06-12 20:34 17人阅读 评论(0) 收藏

    Binary Tree Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6355   Accepted: 2922 Descr ...

  2. E: Sub-process /usr/bin/dpkg returned an error code (1) 解决方案

    转载自:http://www.cnblogs.com/eddy-he/archive/2012/06/20/2555918.html cd /var/lib/dpkg sudo mv info inf ...

  3. java 学习路线《转》

    *第一阶段:Java基础,包括java语法,面向对象特征,常见API,集合框架: *第二阶段:java界面编程,包括AWT,事件机制,SWING,这个部分也可以跳过,用的时候再看都能来及: *第三阶段 ...

  4. CentOS安装zookeeper

    1.zookeeper是个什么玩意? 顾名思义zookeeper就是动物园管理员,他是用来管hadoop(大象).Hive(蜜蜂).pig(小猪)的管理员, Apache Hbase和 Apache  ...

  5. 2016-2017 CT S03E05: Codeforces Trainings Season 3 Episode 5 (2016 Stanford Local Programming Contest, Extended) I

    链接:http://codeforces.com/gym/101116 题意:选六个数,必须出现次数最多,且数字最小,如果出现7优先加入7 解法:排序,出现7优先加入7,最后再将6个数排序 #incl ...

  6. 【Linux】用grep在文档中查找内容

    有时候,我们需要在文档中查找一些内容,常用grep.它在文档查找相关内容并输出匹配行. > 查找某关键字 在system.log中,查找包含keyword的行 grep 'keyword' sy ...

  7. KEIL MDK 5.12帮你快速建工程模板的技巧

    KEIL 5帮你快速建工程模板的技巧 本人使用keil mdk 5.12有一段时间了,发现keil mdk 5.12里面驱动库比较方便.这个新功能可以节省我们的时间,也可以让初学者能尽快上手和掌握这个 ...

  8. 【leetcode❤python】169. Majority Element

    #Method 1import math class Solution(object):    def majorityElement(self, nums):        numsDic={}   ...

  9. BZOJ 3564 信号增幅仪

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3564 题意:给出平面上n个点,画出一个椭圆,椭圆的长轴是短轴的p倍,且长轴的方向为x轴逆时 ...

  10. Know How To Use ID_NULL Function To Search An Object In Oracle Forms

    ID_NULL built in function is used to determine that an object type variable is null or not null in O ...