标签:linux
1.线程标识
就像每个进程有一个进程ID一样,每个线程也都有一个线程ID。进程ID在整个系统中是唯一的,但线程ID不同,线程ID只在它所属的进程环境中有效。线程ID用pthread_t数据类型来表示,通过pthread_equal函数来比较两线程ID是否相同,通过pthread_equal函数可以得到当前线程的ID。
#include <pthread.h>
int pthread_equal(pthread_t tid1,pthread_t tid2);
#include <pthread.h>
pthread_t pthread_self(void);
2.线程的创建
新创建一个线程可以通过pthread_create函数来实现。
pthread_create函数原型:
pthread_create返回成功时,由tidp指向的内存单元被是指为新创建线程的ID,attr参数用来定制线程的各种不同属性。新线程从start_rtn函数的地址开始运行,该函数只有一个无类型指针参数arg。如果需要向函数传入多个参数,那么需要把这些参数放到结构体中,然后把这个结构体的地址作为arg参数传入。
3.进程终止
如果任一线程调用了exit,_Exit或者_exit,那么整个进程就会终止。类似的,如果信号默认的动作是终止进程,那么该信号发送到线程会终止整个进程。
以一下三种方式中的一种退出,可以在不终止整个进程的情况下停止它的控制流。
(1)线程只是从启动例程返回,返回值是线程的退出码。
(2)线程被同一进程中的其他线程取消。
(3)线程调用pthread_exit。
线程可以通过调用pthread_join函数等待同一进程中的其他线程结束。
调用pthread_join的线程将一直阻塞,知道等待的线程退出。
线程可以安排它退出时所要调用的函数,这与进程可以用atexit函数安排进程退出时要调用的函数类似。这与的函数称为线程清理函数。线程可以注册多个线程清理函数,它们执行的顺序与他们注册的顺序相反。
4.线程原语与进程原语之间的比较
我们发现,管理线程的系统调用与管理进程的系统调用有很多相似的地方。
有一点需要注意:在默认的情况下,线程的终止状态会被保存到对该线程调用pthread_join。如果线程之前通过pthread_detach已经处于分离状态,则线程的底层资源会在线程终止时立即被回收,此时不能通过pthread_join获得它的终止状态。
5.线程同步
互斥量(mutex)从本质上说是一把锁,在访问共享资源前对互斥量加锁,在访问完后释放互斥量。对互斥量加锁以后,任何其他试图再次对互斥量加锁的线程都会阻塞,直到加锁的线程释放该互斥锁。
互斥变量是用pthread_mutex_t数据类型表示的。再使用pthread_mutex_t数据类型之前,一定要对它进行初始化。可以把它设置为常量PTHREAD_MUTEX_INITIALIZER,也可以用pthread_mutex_init函数进程初始化。
如果要对互斥量加锁,需要调用pthread_mutex_lock,如果互斥量已经上锁,调用线程将阻塞直到互斥量被解锁。对互斥量解锁,需要调用pthread_mutex_unlock。如果不希望被阻塞,可以用pthread_nutex_trylock函数。
如果想避免永久阻塞的话,可以使用pthread_mutex_timedlock函数设置线程阻塞时间。但线程阻塞到超时时间时,pthread_mutex_timedlock函数返回错误码ETIMEDOUT。
#include <pthread.h>
#include <time.h>
int pthread_mutex_timedlock(pthread_mutex_t *restrict mutex,const struct timespec *restrict tsptr);
例子:
#include <stdio.h> #include <pthread.h> #include <time.h> int main(void) { int err; struct timespec tout; struct tm *tmp; char buf[64]; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_lock(&lock); printf("mutex is locked\n"); clock_gettime(CLOCK_REALTIME,&tout); tmp = localtime(&tout.tv_sec); strftime(buf,sizeof(buf),"%r",tmp); printf("the currrent time is %s\n",buf); tout.tv_sec += 10; err = pthread_mutex_timedlock(&lock,&tout); clock_gettime(CLOCK_REALTIME,&tout); tmp = localtime(&tout.tv_sec); strftime(buf,sizeof(buf),"%r",tmp); printf("the currrent time is %s\n",buf); return -1; }
要在读模式下锁定读写锁,需要调用pthread_rwlock_rdlock。要在写模式下锁定读写锁,需要调用pthread_rwlock_wrlock。不管以何种方式锁住读写锁,都可以调用pthread_rwlock_unlock来解锁。
与互斥量类似,读写锁可以调用trylock来避免线程堵塞以及用timedlock来设定等待的时间。
屏障:屏障是用户协调多个进程并行工作的同步机制。屏障允许每个线程等待,直到所有合作线程都达到某一点,然后从改点继续执行。pthread_join函数就是一种屏障,允许一个线程等待,直到另外一个线程退出。
可以用pthread_barrier_init函数对屏障初始化,用pthread_barrier_destroy反初始化。
#include <pthread.h>
int pthread_barrier_init(pthread_barrier_t *restrict barrier,const pthread_barrierattr_t *restrict attr,unsigned int count);
其中count参数指定在允许所有线程运行下去之前,必须到达屏障的线程数目。使用attr参数指定屏障对象的属性。
使用pthread_barrier_wait的线程在屏障计数为满足条件时会进入休眠状态,直到满足屏障计数,所有的线程都被唤醒。
int pthread_barrier_wait(pthread barrier_t *barrier)
标签:linux
原文地址:http://blog.csdn.net/yao_wust/article/details/41349595