C 语言编程 — pthread 线程操作
Posted 范桂飓
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C 语言编程 — pthread 线程操作相关的知识,希望对你有一定的参考价值。
目录
文章目录
pthread
pthread 是一个 C 线程库,提供了一组借口用于创建、管理和同步线程。
-
pthread_create():用于创建一个新的线程,并将其加入到 Caller(调用者)的线程池中。函数原型:
- 线程标识符指针
- 线程属性:用于指定线程属性,例如:调度策略、优先级等。
- 线程函数指针:线程函数的返回值类型必须是 void* 类型,因为线程函数的返回值会被传递回 pthread_join() 中。
- 传递给线程函数的参数
-
pthread_join():用于等待指定的线程终止,并将该线程的返回值传递给 Caller。如果线程已经终止,那么该函数会立即返回。函数原型:
- 要等待的线程标识符
- 线程返回值指针
-
pthread_mutex_init():用于初始化互斥锁。互斥锁是一种同步机制,用于保护共享资源不被多个线程同时访问。函数原型:
- 互斥锁指针
- 互斥锁属性:用于指定互斥锁的类型,例如:递归锁、非递归锁等。
-
pthread_mutex_lock():用于获取互斥锁。如果互斥锁已经被其他线程占用,那么该函数会阻塞当前线程,直到互斥锁被释放。函数原型:
- 待获取互斥锁指针
-
pthread_mutex_unlock():用于释放互斥锁。如果当前线程持有该互斥锁,那么该函数会将互斥锁的状态设置为可用状态。函数原型:
- 待释放互斥锁指针
-
pthread_cond_init():用于初始化条件变量。条件变量是一种同步机制,用于等待其他线程满足特定条件。函数原型:
- 条件变量指针
- 条件变量属性
-
pthread_cond_wait():用于等待条件变量满足的特定条件,该函数会先释放互斥锁,然后阻塞当前线程,直到其他线程调用pthread_cond_signal() 或 pthread_cond_broadcast()。函数原型:
- 条件变量指针
- 与条件变量相关联的互斥锁指针
线程安全与线程非安全
多线程程序中,线程安全是必须要考虑的因素。
线程安全(Thread Safe)就是在多线程环境中,多个线程在同一时刻对同一份资源(e.g. 寄存器、内存空间、全局变量、静态变量 etc.)进行写操作(读操作不会涉及线程安全的问题)时,不会出现数据不一致。反正,则是线程非安全(None-Thread Safe)的。
为了确保在多线程环境中的线程安全,就要确保数据的一致性,即:线程安全检查。这是一种对资源写操作进行控制的方法论,最简单的方式就是保证多个线程对同一资源的读写顺序,即:加锁机制。
显然,线程安全检查的实现会带来一定的系统开销。相对的,在单线程环境中并不需要考虑线程安全的问题。这就引入了多线程和单线程的执行效率问题,很难一概而论,而是需要针对不同的场景进行性能的测试才可以得出结果。
C 语言的线程非安全函数(不可重入函数)
C语言中大部分函库函数都是线程安全的,但是也有几个常用函数是线程不安全的,也叫不可重入函数。
线程不安全函数原因:是因为这些系统函数使用了某些全局或者静态变量。我们知道,全局变量和静态变量分别对应内存中的全局变量区和静态存储区,这些区域都是可以跨函数跨线程访问的。一旦在多线程环境中使用,在没有加锁的情况下,对同一段内存块进行并发读写,就会造成 Segmentfault/CoreDump 之类的问题。
常见的线程不安全类型有两类:
- 函数依赖了全局变量,并且会修改全局变量,如 rand() 函数的实现每次调用都会修改和读取一个全局的 INT。
- 函数返回了静态变量,如 ctime() 函数。
C 语言的不可重入函数汇总:
C 语言常用的多线程库:一般是 pthread,当然也可以使用 GLIB 中的 gthread,上述的线程安全版本可以兼容这两个库开发的多线程程序。
以上是关于C 语言编程 — pthread 线程操作的主要内容,如果未能解决你的问题,请参考以下文章
linux C语言 多线程竞争(加锁解锁 pthread_mutex_tpthread_mutex_lock()pthread_mutex_unlock() 可解决)
linux C语言 多线程竞争(加锁解锁 pthread_mutex_tpthread_mutex_lock()pthread_mutex_unlock() 可解决)
linux C语言 pthread_t pthread_self()函数(获取调用线程的ID) pthread_equal() 线程id(thread ID)