- 线程标识
就像每个进程有一个进程ID一样,每个线程也有一个线程ID。进程ID在整个系统中是唯一的,但线程ID不同,线程ID只有在它所属的进程上下文中才有意义。
进程ID 用pid_t数据类型表示
线程ID用pthread_t数据类型来表示
线程可以通过调用pthread_self函数获得自身的线程ID#include<pthread.h> int pthread_equal(pthread_t tid1,pthread_t tid2) 返回值:若相等,返回非0数值;否则,返回0
这样可以指定特定的线程完成特定的事情#include<pthread.h> pthread_t pthread_self(void); 返回值:调用线程的线程ID
- 线程创建
新增的线程可以通过调用pthread_create函数创建
当pthread_create成功返回时,新创建线程的线程ID会被设置成tidp指向的内存单元。#include<pthread.h> int pthread_create(pthread_t * restrict tidp, const pthread_attr_t *restrict attr, void *(*start_trn)(void *), void *restrict arg); 返回值: 若成功,返回0, 否则 返回错误编码
attr参数用于定制各种不同的线程属性。(设置为null 创建一个具有默认属性的线程)
新创建的线程从start_trn函数的地址开始运行,该函数只有一个无类型指针参数arg。如果需要向start_trn函数传递的参数有一个以上,那么需要把这些参数放到一个结构体重,然后把这个结构的地址作为arg参数传入。
线程创建时并不能保证哪个线程会先运行:是新创建的线程,还是调用线程。
新创建的线程可以访问进程的地址空间,并且继承调用线程的浮点环境和信号屏蔽字,但是该线程的挂起信号集会被清除
本实例有两个特别之处,需要处理主线程和新线程之间的竞争。第一个特别:主线程需要休眠,如果主线程不休眠,它就可能退出,这样新线程还没有机会运行,整个进程就已经终止了。第二个特别在于新线程通过pthread_self函数获取自己的线程ID,而不是从共享内存读取。#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); }
结果:
main thread: pid 20075 tid 1 (0x1)
new thread:pid 20075 tid 2 (0x2) - 线程终止
单个线程可以通过3种方式退出
1)线程可以简单地从启动例程中返回,返回值是线程的退出码
2)线程可以被同一进程中的其它线程取消
3)线程调用pthread_exit
rval_ptr参数是一个无类型指针。#include<pthread.h> void pthread_exit(void *rval_ptr)
调用线程将一直阻塞,直到制定的线程调用票pthread_exit,从启动例程中返回或者被取消#include<pthread.h> void pthread_join(pthread_t thread,void **rval_ptr)
线程可以调用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 数据类型表示的。使用前必须对其初始化