第11章 线程
2015-09-05 14:01
232 查看
线程标识
就像每个进程有一个进程ID一样,每个线程也有一个线程ID。进程ID在整个系统中是唯一的,但线程ID不同,线程ID只有在它所属的进程上下文中才有意义。
进程ID 用pid_t数据类型表示
线程ID用pthread_t数据类型来表示
线程创建
新增的线程可以通过调用pthread_create函数创建
attr参数用于定制各种不同的线程属性。(设置为null 创建一个具有默认属性的线程)
新创建的线程从start_trn函数的地址开始运行,该函数只有一个无类型指针参数arg。如果需要向start_trn函数传递的参数有一个以上,那么需要把这些参数放到一个结构体重,然后把这个结构的地址作为arg参数传入。
线程创建时并不能保证哪个线程会先运行:是新创建的线程,还是调用线程。
新创建的线程可以访问进程的地址空间,并且继承调用线程的浮点环境和信号屏蔽字,但是该线程的挂起信号集会被清除
结果:
main thread: pid 20075 tid 1 (0x1)
new thread:pid 20075 tid 2 (0x2)
线程终止
单个线程可以通过3种方式退出
1)线程可以简单地从启动例程中返回,返回值是线程的退出码
2)线程可以被同一进程中的其它线程取消
3)线程调用pthread_exit
线程可以调用pthread_cancel函数来请求取消同一进程中的其它线程
线程同步
互斥量 mutex 互斥变量是用pthread_mutex_t 数据类型表示的。使用前必须对其初始化
就像每个进程有一个进程ID一样,每个线程也有一个线程ID。进程ID在整个系统中是唯一的,但线程ID不同,线程ID只有在它所属的进程上下文中才有意义。
进程ID 用pid_t数据类型表示
线程ID用pthread_t数据类型来表示
#include<pthread.h> int pthread_equal(pthread_t tid1,pthread_t tid2) 返回值:若相等,返回非0数值;否则,返回0线程可以通过调用pthread_self函数获得自身的线程ID
#include<pthread.h> pthread_t pthread_self(void); 返回值:调用线程的线程ID这样可以指定特定的线程完成特定的事情
线程创建
新增的线程可以通过调用pthread_create函数创建
#include<pthread.h> int pthread_create(pthread_t * restrict tidp, const pthread_attr_t *restrict attr, void *(*start_trn)(void *), void *restrict arg); 返回值: 若成功,返回0, 否则 返回错误编码当pthread_create成功返回时,新创建线程的线程ID会被设置成tidp指向的内存单元。
attr参数用于定制各种不同的线程属性。(设置为null 创建一个具有默认属性的线程)
新创建的线程从start_trn函数的地址开始运行,该函数只有一个无类型指针参数arg。如果需要向start_trn函数传递的参数有一个以上,那么需要把这些参数放到一个结构体重,然后把这个结构的地址作为arg参数传入。
线程创建时并不能保证哪个线程会先运行:是新创建的线程,还是调用线程。
新创建的线程可以访问进程的地址空间,并且继承调用线程的浮点环境和信号屏蔽字,但是该线程的挂起信号集会被清除
#include "apue.h" #include "pthread.h" void printids(const char *s) { pid_t pid; pthread_t tid; pid = getpid(); tid = pthread_self(); printf("%s pid %lu tid %lu (0x%lx)\n",s,(unsigned long)pid,(unsigned long)tid, (unsigned long)tid); } voud *thr_fn(void *arg) { printftids("new thread:"); return ((void*)0); } int main(void) { int err; err = pthread_create(&ntid,NULL,thr_fn,NULL); if(err!=0) err_exit(err,"can;t create thread"); printids("main thread:"); Sleep(1); exit(0); }本实例有两个特别之处,需要处理主线程和新线程之间的竞争。第一个特别:主线程需要休眠,如果主线程不休眠,它就可能退出,这样新线程还没有机会运行,整个进程就已经终止了。第二个特别在于新线程通过pthread_self函数获取自己的线程ID,而不是从共享内存读取。
结果:
main thread: pid 20075 tid 1 (0x1)
new thread:pid 20075 tid 2 (0x2)
线程终止
单个线程可以通过3种方式退出
1)线程可以简单地从启动例程中返回,返回值是线程的退出码
2)线程可以被同一进程中的其它线程取消
3)线程调用pthread_exit
#include<pthread.h> void pthread_exit(void *rval_ptr)rval_ptr参数是一个无类型指针。
#include<pthread.h> void pthread_join(pthread_t thread,void **rval_ptr)调用线程将一直阻塞,直到制定的线程调用票pthread_exit,从启动例程中返回或者被取消
线程可以调用pthread_cancel函数来请求取消同一进程中的其它线程
#include<pthread.h> int pthread_cancel(pthread_t tid); 返回值:若成功 返回0 否则 返回错误编号一个线程可以建立多个清理处理程序。处理程序记录在栈中,也就是说,它们的执行顺序与它们注册时相反。
#include<pthread.h> int pthread_cleanup_push(void (*trn)(void *),void *arg); void pthread_cleanup_pop(int execute)
线程同步
互斥量 mutex 互斥变量是用pthread_mutex_t 数据类型表示的。使用前必须对其初始化
相关文章推荐
- 华为OJ 寻找大小字母个数
- java注解
- android本地轻量级缓存
- HDU5237 Base64 大模拟
- 部分手机RadioButton作为Tab键不居中问题
- cat head tail
- Android设计模式——抽象工厂模式(Abstract Factory)
- java环境搭建(及安装问题“No repository found containing”解决) 并创立第一个java程序
- makefile特殊符号介绍
- 流程图符号及流程图的例子
- YII2 RBAC用法
- ToggleButton,Switch,RatingBar的使用
- grub 应用
- 最小生成树和最短路径
- Android ADT 中的项目迁移到 Android Studio出现编码乱码问题
- 黑马程序员java之反射
- Hadoop 案例4----平均成绩
- VM10安装CentOS6.5网络配置
- Bungee Jumping---hdu1155(物理题)
- win7启动后报丢失nscmk.dll解决解决方式