线程相关函数 线程退出 互斥锁 信号量 条件变量

线程是CPU的最小调度单元,每个核上都可以运行一个线程。

 

多进程

缺点:

进程是互相隔离的,多进程之间的通信和同步是效率低。

CPU进行进程切换效率低

创建一个进程比创建线程耗费的内存多

优点:

单核CPU可以完成多任务,在宏观上并行。

 

线程:

优点:

线程保留了多进程的多任务特性,但是线程之间的通信效率更高,切换线程的效率也更高。

多核的CPU可以保证多线程可以同时运行在多个核上(CPU不能保证多个进程可以同时运行在多核上)

使CPU利用率更高

 

线程就是在保留了进程的多任务特性的基础上,优化了进程的通信和进程切换的效率。

 

 

线程创建与回收

(1)pthread_create 用来创造子线程的 创建成功立刻调用一次

(2)pthread_join 用来等待(阻塞)回收子线程

(3)pthread_detach 用来分离子线程,分离后主线程不必再去回收子线程

(4)pthread_attr_init 属性初始化的函数

线程取消

(1)pthread_cancel 一般都是主线程调用该函数去取消(让它赶紧死)子线程

(2)pthread_setcancelstate 子线程设置自己是否允处理cancel信号

(3)pthread_setcanceltype 取消模式(异步取消<立刻死> or 同步取消<等待适当时机死>)

线程函数退出相关

(1)pthread_exit与return退出

(2)pthread_cleanup_push 注册一个清理函数 清理锁

(3)pthread_cleanup_pop 注销清理函数

 

线程私有数据

int pthread_key_creadte(pthread_key_t *key,void (*destr_fuction) (void *)); 创建键值

int pthread_setspecific(pthread_key_t key,const void * pointer)); 设置

void * pthread_getspecific(pthread_key_t key); 获取

int pthread_key_delete(ptherad_key_t key); 删除

 

主线程退出:

主线程中如果从main函数返回或是调用了exit函数退出主线程,则整个进程终止,此时所有的其他线程也将终

主线程调用pthread_exit函数,则仅仅是主线程消亡,进程不会结束

 

线程取消:

线程取消就是向目标线程发送Cancel信号,但对这个信号的处理方式由线程自身决定(取消)。

if 是否接受取消信号 then

if 异步取消 then

立刻结束

else

运行到下个取消点结束(多数阻塞函数的调用位置都是取消点 pthread_join()、pthread_testcancel()、pthread_cond_wait()、pthread_cond_timedwait()、sem_wait()、sigwait())

end

end

 

触发终止线程的两种方式:

正常终止 :return 和主动pthread_exit(),

非正常终止:外部干扰导致退出

无论是那种方式退出 线程的资源都会被释放

对于非正常终止 要保证退出前资源可以正确清理 使用 pthread_cleanup_push/pthread_cleanup_pop。在两个函数中间的终止操作会调用清理函数,清理资源(如释放锁)

 

终止后清理资源方式:

线程为分离状态:操作系统自动回收资源。

pthread_join() :其他进程阻塞等待线程结束 并释放资源

 

 

其他:当线程退出时,线程占用的资源并不会释放。

 

 

什么是线程同步???

线程同步就是控制线程的执行顺序,保证线程安全(多个线程访问同时访问同一个数据)

 

 

同步方式:

互斥锁:

pthread_mutex_init pthread_mutex_destroy

pthread_mutex_lock pthread_mutex_unlock

 

信号量:

int sem_init 

int sem_wait(sem_t *sem); 给信号量减1;对一个值为0的信号量调用sem_wait,这个函数将会等待直到有其它线程使它不再是0为止。

int sem_post(sem_t *sem); 给信号量的值加1;

int sem_destroy

 

条件变量

pthread_cond_init pthread_cond_destroy

pthread_cond_wait pthread_cond_signal/pthread_cond_broadcast

互斥锁不同,条件变量是用来等待而不是用来上锁的。条件变量用来自动阻塞一个线程,直到某特殊情况发生为止。一个线程等待"条件变量的条件成立"而挂起;另一个线程使"条件成立"(给出条件成立信号)。

 

多线程为什么需要同步??

为了解决多线程间共享数据问题,如果数据只是读那么没有影响。

为什么共享数据会发生问题???

对共享数据的操作如果不是原子不可打断的(单个汇编指令完成的操作为原子 或 加锁),那么在执行过程中线程可能会被挂起,其他线程也可以运行操作这个数据,就会导致线程见数据不安全。

例子:

x++和++x。

其实类似x++, x+=2, ++x这样的操作在多线程环境下是需要同步的。因为X86会按三条指令的形式来处理这种语句:从内存中读x的值到寄存器中,对寄存器加1,再把新值写回x 所处的内存地址。

例如有两个线程,它们按照如下顺序执行(注意读x和写回x是原子操作,两个线程不能同时执行):

time Thread 1 Thread 2

0 load eax, x

1 load eax x

2 add eax, 1 add eax, 1

3 store x, eax

4 store x, eax

中断的位置对程序的输出结果是有影响的,这就是导致多线程问题的根本原因。所以引入线程同步解决,保证某部分数据或代码的操作是原子的。

 

同步、互斥区别??

互斥不要求线程按一定顺序执行,同步是为了让线程按一定顺序执行。

同步是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。可以说同步是特殊的互斥。

 

 

互斥锁与信号量:

互斥锁是一种特殊的信号量,值只能是0 1 ,信号量值 可以是任意非0整数。互斥锁的加锁和解锁操作必须在同一线程中,信号量可以一个线程释放,另一个线程得到。

 

 

条件变量:条件变量用于同步 阻塞的等待某一条件满足 互斥锁是争夺资源 用于互斥

为什么要和互斥锁一起使用???

https://www.jb51.net/article/102764.htm

 

 

你可能感兴趣的:(网络)