APUE,TLPI读书笔记——线程

线程:

一个进程包含多个线程,共享进程的全局内存区域

线程的内存分布:

APUE,TLPI读书笔记——线程_第1张图片

线程会继承进程部分信息,也会有一些独立的信息:详见pthread

线程函数的返回值与errno的值相同,可以对此进行防御式编程。


详见pthread

pthread_create();//线程创建

pthread_exit();//线程终止

pthread_self();//返回PID

pthread_equal();//判断PID是否相等

pthread_join();//等待线程终止,可以获取线程返回值

pthread_detach();//分离线程,不关心其返回值,让其成为后台线程

线程属性pthread_attr_t类型



线程同步:

1.互斥量:

1)静态分配 pthread_mutex_t mtx = PTHREAD_MUTEX_INITALIZER;

2)动态分配,使用函数:pthread_init();pthread_mutex_destory();

3)加锁与解锁:pthread_mutex_lock();   pthread_mutex_unlock();

4)其他解锁函数:pthread_mutex_trylock();  pthread_mutex_timelock();

互斥量的死锁避免:应该使用相同顺序对一组互斥量加锁。


2.条件变量:

1)静态分配  pthread_cond_t cond = PTHREAD_COND_INITALIZER;

2)动态分配:pthread_cond_init();pthread_cond_destory();

3)操作参数:

pthread_cond_signal();//唤醒至少一条阻塞线程

pthread_cond_broadcast();//唤醒所有阻塞线程

pthread_cond_wait();//使用时,先对参数中的mutex解锁,然后阻塞到条件满足唤醒线程再上锁

pthread_cond_wait();//加上定时器cond_wait


//以下方式使用较少,了解即可

3.读写锁:

详见:rwlock

4.自旋锁:

pthread_spin_init();等等。与mutex类似,但是不是使进程阻塞,而是一直处于忙等待(自旋)的阻塞状态。用于持有锁时间短的情况。常用于底层,实现其他锁机制。

5.屏障:

pthread_barrier_init();等等。协调多个线程,直到合作线程到达某一点

线程安全与线程存储

线程安全函数:

pthread_once();//无论多少线程调用,只执行一次。在C++的DCLP可以配合使用(C++11多线程标准库中也有类似的函数)

线程特有数据:

为线程单独开辟的数据区(与pthread_once()配合)

线程特有数据会包含一个全局(进程范围内)数组,存在线程特有数据的key信息。

每个线程包含一个数组存放分配的线程特有数据块的指针。

static void destructor(void* ptr)
{
	free(ptr);
}


void thread_perr(char* f, int s)
{
	fprintf(stderr, "%s : %s", f, strerror(s));
}


static void make_key()
{
	int s;
	s = pthread_key_create(&key, destructor);//在线程退出的时候调用destructor               
	if (s != 0)
		thread_perr("pthread_key_create", s);
}


void func() 
{
	void *ptr;               
	int s;               
	s = pthread_once(&key_once, make_key);//保证只创建一次
	if (s != 0)
		thread_perr("pthread_once", s);
	if ((ptr = pthread_getspecific(key)) == NULL) //获取key的缓冲区地址                {                {
		ptr = malloc(OBJECT_SIZE);//分配内存                                          
		s = pthread_setspecific(key, ptr);//保存缓冲区地址
	if (s != 0)
		thread_perr("pthread_getspecific", s);               
		//...其他操作
}

线程局部存储:

在全局或静态变量前包含__thread关键字



线程取消:

pthread_cancel();

pthread_setcancelstate();

pthread_setcancelstyle();

线程取消请求发送后会一直阻塞到线程抵达cancellation point。是cancellation point详见:pthread

pthread_testcancel();//测试可取消性

线程清理:

pthread_cleanup_push();pthread_cleanup_pop();//向线程清理函数栈注册和移出函数 详见:pthread_cleanup_push 与pthread_cleanup_pop

异步取消:

设置取消类型为PTHREAD_CANCEL_AYSNCCHRONOUS,可实现线程异步取消,

异步取消任何时点即可取消(清理函数也无法获取线程取消调用时的具体情况,因此可异步取消的线程不分配任何资源,不获取mutex等等)



你可能感兴趣的:(APUE,TLPI读书笔记——线程)