POSIX基本的几个线程管理函数见下表:
------------------------------------------------------------------------------------------
                     POSIX函数                                                         描述
-------------------------------------------------------------------------------------------
                    pthread_create                                   创建一个线程
                    pthread_self                                       找出自己的线程ID
                    pthread_equal                                    测试2个线程ID是否相等
                    pthread_detach                                  设置线程以释放资源
                    pthread_join                                        等待一个线程
                    pthread_cancel                                   终止另一个线程
                    pthread_exit                                        退出线程,而不退出进程
                    pthread_kill                                         向线程发送一个信号
-------------------------------------------------------------------------------------------
 
(1)线程ID、获取和比较
POSIX线程由一个pthread_t类型的ID来引用。线程可以通过调用pthread_self ()函数获得自己的线程ID,这里没有对pthread_self 定义错误。
 
==========================
概要:
#include <pthread.h>                     
pthread_t   pthread_self (void);   
==========================
 
由于pthread_t  可能是一个结构,所以不能由==来直接进行比较。这里可以使用函数pthread_equal()来比较线程ID是否相等,这里没有对pthread_equal定错误,如果两个线程ID相等,返回非0值,否则返回0.
 
============================================
概要:
#include <pthread.h>                     
int   pthread_equal(pthread_t  t1, pthread_t  t2 );   
============================================
 
(2)创建线程
可以使用pthread_create()创建一个线程。POSIX的pthread_create()创建的线程是可以直接运行的,而不需要一个单独的启动操作。
 
==========================================
概要:
#include <pthread.h>
int pthread_create(pthread_t *restrict thread,
                   const pthread_attr_t *restrict attr,
                   void *(*start_routine)(void *), 
                   void *restrict arg);
==========================================
在上述函数中,thread指向新创建的线程ID;参数attr表示一个封装了线程各种属性的属性对象(比如栈大小、调度等信息,后面会专门介绍),如果attr为NULL,则使用默认属性进行创建;第三个参数start_routine是线程开始执行时调用的函数名字;第四个参数arg指针指向的数据是start_routine的参数。如果成功,函数返回0,否则返回非零错误码。
 
下面例子中的代码就是连续创建10个线程,线程中执行的代码仅为打印自己的线程ID,和所属进程ID:
 
#include <pthread.h>
#include <stdio.h> void *print_thread(int *i)
{
fprintf(stderr,"number:%d,pid:%d,tid:%lld.\n",*i,getpid(),(long long)pthread_self());
return NULL;
} int main(int argc, char* argv[ ] )
{
pthread_t tids[];
int i;
for(i=;i<;i++)
{
if(pthread_create(&tids[i],NULL,print_thread,&i)==-)
{
fprintf(stderr,"\nERROR: fail to creat thread.");
tids[i]= pthread_self();
}
}
return ;
}
执行结果:
gaolu@gaolu-desktop:~$ ./thr
number:0,pid:5579,tid:3085089680.
number:1,pid:5579,tid:3076696976.
number:2,pid:5579,tid:3068304272.
number:3,pid:5579,tid:3059911568.
number:4,pid:5579,tid:3051518864.
number:5,pid:5579,tid:3043126160.
number:6,pid:5579,tid:3034733456.
number:7,pid:5579,tid:3026340752.
number:8,pid:5579,tid:3017948048.
number:9,pid:5579,tid:3009555344.
gaolu@gaolu-desktop:~$
 
(3)线程的分离(detach)和连接(join)
一般情况下,线程在退出时,是不会释放它的资源的;
 
如果将线程分离,即创建线程以后调用pthread_detach(tid)或者线程自身调用pthread_detach(pthread_self())都可以,它设置线程的内部选项来说明,线程退出以后存储空间可以被重新收回,分离线程退出时不会报告他们的状态。
 
如果线程没有分离,那么它是可以接合(join)的,pthread_join和进程级别的函数wait_pid非常类似,该函数将调用线程挂起,直到第一个参数指定的目标线程终止为止。如果创建线程对子线程调用了pthread_join(), 子线程退出以后,资源在进程退出以后被回收。参数value_ptr为指向返回值的指针,这个返回值是目标线程return 或者传递给pthread_exit()的。
 
为了防止内存泄漏,长时间运行的线程最终应该为每个线程调用pthread_join() 或者pthread_detach()。
 
===========================================
概要:
#include <pthread.h>
int pthread_join(pthread_t th, void **value_ptr )
int pthread_detach(pthread_t thread )
===========================================
 
下面一个示例程序演示了pthread_detach和pthread_join之间的关系。
 
(1)子线程将自己detach了,这种情况下线程是不能被join的。
#include <pthread.h>
#include <stdio.h>
void *print_thread(void *ptr)
{
if(pthread_detach(pthread_self())==)
{
fprintf(stderr,"tid:%lld,I have detached myself successfully.\n",(long long)pthread_self( ) );
}
else
{
fprintf(stderr,"\nERROR:detach failed.");
}
return NULL;
}
int main(int argc, char* argv[])
{
pthread_t tid;
int *exitcode;
if(pthread_create(&tid,NULL,print_thread,NULL)==-)
{
fprintf(stderr,"\nERROR: fail to creat thread.");
}
fprintf(stderr,"my pid is %d.\n",getpid());
if(pthread_join(tid,&exitcode)!=)
{
fprintf(stderr,"ERROR: fail to join thread.\n");
}
else
{
fprintf(stderr,"parent end successfully.\n");
} return ;
}
gaolu@gaolu-desktop:~$ ./thr
tid:3084360592,I have detached myself successfully.
my pid is 5652.
ERROR: fail to join thread.
gaolu@gaolu-desktop:~$
 
(2)修改创建的线程只是做了普通的打印信息,join可以执行成功。
void *print_thread(void *ptr)
{
     fprintf(stderr,"My tid:%lld.\n",(long long)pthread_self());
}
gaolu@gaolu-desktop:~$ ./thr
My tid:3085216656.
my pid is 5702.
parent end successfully.
gaolu@gaolu-desktop:~$ 
(4)线程退出和取消
线程return一个指针value_ptr的相当于隐式地调用了pthread_exit(value_ptr)函数。如果进程的最后一个线程调用了pthread_exit,进程就会带着状态返回值0退出。
 
对于一个被join了的线程来说,其返回值vlaue_ptr是可用的。也就是说value_ptr一定是要指向线程结束以后还存在的数据------这个问题可以通过几种方式解决:比如创建线程给被创建的线程传递参数时,参数中传递一个指针,作为被创建线程的返回值,这样返回值是位于创建线程的栈上;另外在被创建线程malloc内存,将指针作为返回值使用也可以。
 
另外,线程可以通过取消机制迫使其他线程返回。线程通过执行pthread_cancel()来请求取消另一个线程,该函数在发出取消请求以后就返回了,而不需要阻塞;而实际结果由目标线程的类型和取消状态决定(状态可以通过函数设置的)。
 
==================================================
概要:
#include <pthread.h>
int pthread_exit(void *value_ptr );
int pthread_cancel( pthread_t thread );
int pthread_setcancelstate (int state, int *oldstate);
==================================================
 
如果线程收到cancel的请求时,处于PTHREAD_CANCEL_ENABLE,它就接受取消请求;否则如果处于PTHREAD_CANCEL_DISABLE的状态,取消请求就会被保持在挂起状态。默认情况下,线程处于PTHREAD_CANCEL_ENABLE状态。
 
 
 

本文出自 “淡泊明志,宁静致远” 博客,请务必保留此出处http://keren.blog.51cto.com/720558/176759

POSIX多线程——基本线程管理函数介绍的更多相关文章

  1. Pthread:POSIX 多线程程序设计【转】

    转自:http://www.cnblogs.com/mywolrd/archive/2009/02/05/1930707.html#phtread_ref POSIX 多线程程序设计  Blaise ...

  2. [posix]Posix多线程编程

    就不排版了,可以到原作者博客下看 转自:http://www.cnblogs.com/zhangsf/archive/2013/09/09/3309867.html 目录表  摘要 译者序 Pthre ...

  3. iOS多线程编程指南(二)线程管理

    当应用程序生成一个新的线程的时候,该线程变成应用程序进程空间内的一个实体.每个线程都拥有它自己的执行堆栈,由内核调度独立的运行时间片.一个线程可以和其他线程或其他进程通信,执行I/O操作,甚至执行任何 ...

  4. C++ 11 多线程--线程管理

    说到多线程编程,那么就不得不提并行和并发,多线程是实现并发(并行)的一种手段.并行是指两个或多个独立的操作同时进行.注意这里是同时进行,区别于并发,在一个时间段内执行多个操作.在单核时代,多个线程是并 ...

  5. ios 多线程开发(二)线程管理

    线程管理 iOS和OS X中每一个进程(或程序)由一个或多个线程组成.程序由一个运行main方法的线程开始,中间可以产生其他线程来执行一些指定的功能. 当程序产生一个新线程后,这个线程在程序进程空间内 ...

  6. posix多线程--三种基本线程编程模型

    本文介绍了三种构建线程解决方案的方式. 一.流水线:每个线程执行同一种操作,并把操作结果传递给下一步骤的线程. 代码示例如下:终端输入一个int值,每个线程将该值加1,并将结果传给下一个线程. #in ...

  7. (转)C++ 11 多线程--线程管理

    说到多线程编程,那么就不得不提并行和并发,多线程是实现并发(并行)的一种手段.并行是指两个或多个独立的操作同时进行.注意这里是同时进行,区别于并发,在一个时间段内执行多个操作.在单核时代,多个线程是并 ...

  8. 多线程的基本概念和Delphi线程对象Tthread介绍

    多线程的基本概念和Delphi线程对象Tthread介绍 作者:xiaoru    WIN 98/NT/2000/XP是个多任务操作系统,也就是:一个进程可以划分为多个线程,每个线程轮流占用CPU运行 ...

  9. C# 多线程的自动管理(线程池) 基于Task的方式

    C# 多线程的自动管理(线程池) 在多线程的程序中,经常会出现两种情况:    1. 应用程序中线程把大部分的时间花费在等待状态,等待某个事件发生,然后给予响应.这一般使用 ThreadPool(线程 ...

随机推荐

  1. JavaScript超大整数加法

    原文:JavaScript超大整数加法 什么是「超大整数」? JavaScript 采用 IEEE754标准 中的浮点数算法来表示数字 Number. 我也没花时间去详细了解 IEEE754标准 ,但 ...

  2. SQL Server 2008 R2中,变表的右键弹出菜单中的“选择前1000行”为“选择所有行”

    原文:SQL Server 2008 R2中,变表的右键弹出菜单中的"选择前1000行"为"选择所有行" 从SQL Server 2008开始,微软为了提高查询 ...

  3. Visual Studio 单元测试之四---Generic测试

    原文:Visual Studio 单元测试之四---Generic测试 这里的Generic我觉得理解为外部测试更合适.因为在这种测试模式下Visual Studio只是启动一个外部的程序,然后通过返 ...

  4. VS代码生成工具ReSharper发布8.1版本

    ReSharper是一个著名的VS代码生成工具,能帮助VS成为一个更佳的IDE.JetBrains公司今天发布了ReSharper最新版本8.1. 本次新版本更新涉及到打印稿.与VS2013集成.代码 ...

  5. 强大的jquery-制作选项卡

    最近在学习jquery,特地把今天写的一个选项卡源码贴出来.只是做只是梳理,大神们请不要吐槽,如果有更好的方法,欢迎指点.谢谢. css <style> #tab div{ width:2 ...

  6. Dev环境中的集成测试用例执行时上下文环境检查(实战)

    Dev环境中的集成测试用例执行时上下文环境检查(实战) Microsoft.NET 解决方案,项目开发必知必会. 从这篇文章开始我将分享一系列我认为在实际工作中很有必要的一些.NET项目开发的核心技术 ...

  7. Android借助Application重写App的Crash(简易版)

    MainActivity如下: package cn.testcrash; import android.app.Activity; import android.os.Bundle; /** * D ...

  8. 在 InstantRails 环境下,安装使用 redMine

    在 InstantRails 环境下,安装使用 redMine 分类: Redmine2009-06-01 10:35 732人阅读 评论(0) 收藏 举报 characterrailsencodin ...

  9. 什么是Angular JS?

    Angular JS学习笔记——什么是Angular JS? Angular JS是一个由Google维护的开源的Javascript框架,主要作者为: Misko Hevery(angular JS ...

  10. c# 窗体最小化后截图实现

    我们知道,当我们需要对Control进行截图时,我们可以使用Control.DrawToBitmap()进行截图, 那么问题来了,当我们的窗体最小化了,我们还怎么截图呢? 当窗体最小化的时候,我们知道 ...