线程同步机制:http://www.cnblogs.com/zheng39562/p/4270019.html

一、基础知识

1:基础知识。

  1,线程需要的信息有:线程ID,寄存器,栈,调度优先级和策略,信号屏蔽字,errno变量和线程私有数据。

  2,进程的所有信息对所有线程都是共享的。

  3,是否支持有多线程有以下两种方式测试:

    1)编译时确定:#ifdef _POSIX_THREADS

    2)运行时确定:sysconf函数调用 _SC_THREADS 常用。

  4,线程ID。

    1)一个进程中,线程ID具有唯一性。线程ID依赖与进程后,才有意义。

    2)线程ID表示类型:pthread_t类型

  5,变量增量操作的步骤:

    1)变量值从 内存单元 读入 寄存器。

    2)寄存器中对变量进行修改。

    3)将变量值 写回 内存单元

    4)所以,多个线程试图同时修改同一变量时,需要同步。

  6,进程资源和线程的关系:

    1)每个线程都有自己的信号屏蔽字。但,信号处理是所有线程共享的。所以,线程对信号的处理会影响所有线程。

    2)闹钟定时是进程资源。所有线程共享使用。

    3)pread / pwrite 函数在多线程读写比较适用。因为其可以保存多个线程的读写偏移量,从而保证不会被覆盖。

2:线程创建和终止。

  1,线程创建。

    1)并不能确定哪个线程先运行(和子进程创建类似)。

    2)创建函数create失败后,通常会返回错误码。

  2,线程终止。

    1)任意线程调用 exit, _Exit, _exit函数都会使进程终止。(所以不可以使用此方式终止单个线程)

    2)从启动例程返回。返回值时线程退出码。

    3)可以被同进程中的其他线程取消。

    4)线程调用pthread_exit函数。

3:线程的数据和安全

  1,线程安全:一个函数在相同时间点可以被多个线程安全地调用。

    1)当一个函数是可重入时,那就是线程安全的。

    2)异步信号安全。

  2,可重入函数。

    1)当处理信号中断时,部分函数可能更改信息,导致中断处理结束后,无法正确的从中断点继续执行程序(信息错位)。

    2)可重入函数保证再中断期间调用这些函数,不会导致信息错位。

    3)可重入函数又被称为异步信号安全的函数。

  3,线程私有数据:具体操作见函数。

5:进程和线程功能/函数对应表

进程原语 线程原语 描述

fork

pthread_create 创建新的控制流
exit pthread_exit 从先有控制流中退出
waitpid pthread_join 从控制流中得到退出状态
atexit pthread_cancel_push 注册在退出控制流时的调用的函数
getpid pthread_self 获取控制流的ID
abort pthread_cancel 请求控制流的非正常退出。

二、相关函数。

1:线程操作函数。

 比较线程ID大小。
  int pthread_equal( pthread_t tid1, pthread_t tid2 )
获取自身线程ID。
  pthread_t pthread_self( void );
创建线程。
  int pthread_create( pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void *), void *restrict arg);
  // 1 参数arg用于定制各种不同的线程属性
线程终止。   
  void pthread_exit( void *rval_ptr );
获得线程退出状态。   
  int pthread_join( pthread_t thread, void **rval_ptr );   
  // 1 参数rval_ptr包含返回码。
取消其他线程(同进程中使用)   
  int pthread_cancel( pthread_t tid );   
  // 1 仅仅提出请求。并不强制终止。
线程清理处理程序(类似进程的atexit)。   
  void pthread_cleanup_push( void (*rtn)(void *), void *arg);   
  void pthread_cleanup_pop( int execute );   
  // 1 参数execute=0时,清理函数将不被调用。   
  // 2 每次调用pop函数时,都出删除上一个push的清理程序。   
  // 3 这些函数被实现为宏。需要注意{}等匹配。   
  // 4 清理程序的注册和执行顺序相反。
分离线程。   
  int pthread_detach( pthread_t tid );
清除子进程的锁
  int pthread_atfork( void (*prepare)(void), void (*parent)(void), void (*child)(void) );   
  // 1 注册和执行顺序相反。
上述函数中。部分无类型指针,可以传递的值有很多,甚至可以时一个结构体。

2,线程属性 相关函数。

 线程属性 初始化 和 类析构函数
  int pthread_attr_init( pthread_attr_t *attr );
  int pthread_attr_destroy( pthread_attr_t *attr );
获取/设置 分离状态。
  int pthread_attr_getdetachstats( const pthread_attr_t *restrict attr, int *detachstate );
  int pthread_attr_setdetachstats( pthread_attr_t *attr, int *detachstate );
  // 1 参数detachstate只有两个值:PTHREAD_CREATE_ DETACHED/JOINABLE.
获取/设置 线程栈属性 stackaddr。
  int pthread_attr_getstack( const pthread_attr_t *restrict attr, void **restrict stackaddr, size_t *restrict stacksize );
  int pthread_attr_setstack( pthread_attr_t *attr, void *stackaddr, size_t stacksize );
  // 1 stackaddr线程属性定义为栈的最低内存地址。是起始位置,还是结尾位置取决于栈的发展方向。通常是结尾(栈由高向低)
获取/设置 栈大小属性 stacksize。
  int pthread_attr_getstacksize( const pthread_attr_t *restrict attr, size_t *restrict stacksize );
  int pthread_attr_setstacksize( pthread_attr_t *attr, size_t stacksize );
获取/设置 线程栈末尾缓冲区大小 guardsize。
  int pthread_attr_getguardsize( const pthread_attr_t *restrict attr, size_t *restrict guardsize );
  int pthread_attr_setguardsize( pthread_attr_t *attr, size_t guardsize );

3:线程私有数据。

 创建一个键
  int pthread_key_create( pthread_key_t *keyp, void (*destructor)(void *));
  // 1 可以指定一个析构函数(第二个参数)
  // 2 每个线程的键的独立的:即相同的KEY在不同线程中表示不同的数据。
取消一个键和特定线程的关联。
  int pthread_key_delete( pthread_key_t key );
  // 1 不激活关联的析构函数。
使一个键只被调用一次:使不同线程拥有不同的键。
  int pthread_once( pthread_once_t *initflag, void (*initfn)(void));
获取/设置 键内数据。
  void *pthread_getspecific( pthread_key_t key );
  int pthread_setspecific( pthread_key_t key , const void *value );

4:特殊线程属性:可取消状态 和 可取消类型。

 设置 可取消状态
  int pthread_setcancelstate( int state, int *oldstate );
  // 1 取消状态有两种: PTHREAD_CANCEL_ ENABLE/DISABLE
设置 自己的取消点。
  void pthread_testcancel( void );
  // 1 取消状态作用:取消请求发出后,会在下一个取消点进行取消操作(个人理解退出线程)。
修改取消类型。
  int pthread_setcanceltype( int type, int *oldtype )

5:线程和信号

 线程阻止信号发送
  int pthread_sigmask( int how, const sigset_t *restrict set, sigset_t *restrict oset );
等待信号。
  int sigwait( const sigset_t *restrict set, int *restrict signop );
  // 1 参数set指定线程等待的信号集。
  // 2 参数signop 包含发送信号的数量。
  // 3 在使用函数前,必须先阻塞它等待的信号。(参数一)
  // 4 函数在执行时,会取消信号集的阻塞状态。
发送信号给线程。
  int pthread_kill( pthread_t thread, int signo );
  // 1 参数signo传递0,可以检查线程是否存在

三、

最新文章

  1. Cookie和Session的那些事儿
  2. php中的cookie用法
  3. [汇编] C语言中嵌入汇编
  4. Vim 练级攻略
  5. linux死锁检测的一种思路【转】
  6. C++11新特性:Lambda函数(匿名函数)
  7. VC2008下CRichEditView加载RichEdit4.1版本(还有一些类似的文章)
  8. Asp.net - The type or namespace name 'App_Code' does not exist in the namespace 'xxx' (are you missing an assembly reference?)
  9. QT绘制系统简介
  10. mysql常用操作命令
  11. 手动安装Nginx
  12. .NET ClrProfiler ILRewrite 商业级APM原理
  13. MySQL分布式事物(XA事物)的使用
  14. codeforces618B
  15. ML.NET 0.10特性简介
  16. 阿里云服务器搭建FTP
  17. Linux性能测试分析命令_top
  18. 30个你 “ 不可能全部会做 ” 的javascript题目-答案解释
  19. Spring Boot 概述
  20. 在spring boot上基于maven使用redis——批量匹配并删除 (二)

热门文章

  1. Image的Stride
  2. Myeclipse中如何修改Tomcat的端口号
  3. 浅谈localStorage本地存储
  4. sql中NULL的问题
  5. js控制浏览器后退
  6. Django1.7官方文档中的tutorial——翻译
  7. 雅思创始人Keith Taylor谈英语学习
  8. mysql innodb_double_write特性
  9. joseph-约瑟夫环问题
  10. rpm包制作