首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
01|快速回顾:一个 C 程序的完整生命周期
02|程序基石:数据与量值是如何被组织的?
03|计算单元:运算符是如何工作的?
04|控制逻辑:表达式和语句是如何协调程序运行的?
05|代码封装:函数是如何被调用的?
06|整合数据:枚举、结构与联合是如何实现的?
07|操控资源:指针是如何灵活使用内存的?
08|编译准备:预处理器是怎样处理程序代码的?
09|标准库:字符、字符串处理与数学计算
10|标准库:深入理解标准 IO
11|标准库:非本地跳转与可变参数是怎样实现的?
12|标准库:你需要了解的 C 并发编程基础知识有哪些?
13|标准库:如何使用互斥量等技术协调线程运行?
14|标准库:信号与操作系统软中断有什么关系?
15|标准库:日期、时间与实用函数
16|标准库:断言、错误处理与对齐
17|极致优化:如何实现高性能的 C 程序?
18|生产加速:C 项目需要考虑的编码规范有哪些?
19|生产加速:如何使用自动化测试确保 C 项目质量?
20|生产加速:如何使用结构化编译加速 C 项目构建?
21|实战项目:一个简单的高性能 HTTP Server
22|可执行二进制文件里有什么?
23|进程是如何使用操作系统内存的?
24|编译器在链接程序时发生了什么?
25|程序可以在运行时进行链接吗?
26|C 程序的入口真的是 main 函数吗?
27|ABI 与 API 究竟有什么区别?
28|程序如何与操作系统交互?
当前位置:
首页>>
技术小册>>
深入C语言和程序运行原理
小册名称:深入C语言和程序运行原理
### 章节 12:标准库:你需要了解的 C 并发编程基础知识 在深入探讨C语言的并发编程时,我们不得不提到C标准库(C Standard Library)及其扩展,这些库提供了构建多线程程序的基础。尽管C标准本身直到C11标准之前都没有直接支持多线程编程,但C程序员一直通过POSIX线程(pthreads)、OpenMP等第三方库来实现并发性。从C11开始,C标准库引入了`<threads.h>`头文件(在部分实现中可能作为可选功能),以及内存模型和原子操作的支持,这标志着C语言在并发编程领域迈出了重要一步。然而,鉴于`<threads.h>`的普及程度和广泛支持度,本章节将主要围绕更广泛接受的方法和概念展开讨论,同时也会简要提及C11及之后版本的标准库对并发编程的支持。 #### 1. 并发与并行的基本概念 在深入具体技术之前,了解并发(Concurrency)与并行(Parallelism)的基本概念至关重要。并发指的是同时处理多个任务的能力,但这些任务并非在同一时刻同时执行,而是轮流使用CPU时间片(时间共享)。而并行则是指同时有多个任务在同一时间点内真正同时执行,这通常需要多核处理器的支持。 #### 2. POSIX线程(pthreads) POSIX线程(pthreads)是C语言中最广泛使用的并发编程库之一,它定义了一套用于创建、同步、调度和管理线程的API。在POSIX兼容的系统(如Linux、MacOS)上,pthreads几乎成了多线程编程的标准。 ##### 2.1 创建线程 在pthreads中,`pthread_create`函数用于创建一个新线程。其原型如下: ```c int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); ``` 这里,`thread`是指向新线程ID的指针,`attr`是线程属性(通常为NULL表示默认属性),`start_routine`是新线程执行的函数,`arg`是传递给该函数的参数。 ##### 2.2 线程同步 为了避免数据竞争和其他并发问题,pthreads提供了多种同步机制,包括互斥锁(mutexes)、条件变量(condition variables)、读写锁(readers-writers locks)等。 - **互斥锁**:确保同一时间只有一个线程可以访问共享资源。`pthread_mutex_lock`和`pthread_mutex_unlock`用于加锁和解锁。 - **条件变量**:与互斥锁一起使用,允许线程在等待某个条件成立时阻塞,并在条件满足时被唤醒。 ##### 2.3 线程终止与清理 线程可以通过调用`pthread_exit`函数终止,该函数允许线程指定退出状态。主线程可以调用`pthread_join`等待一个线程结束,并获取其退出状态。 #### 3. C11及更高版本的并发支持 从C11开始,C标准库引入了对并发编程的初步支持,主要集中在原子操作和线程局部存储上。 ##### 3.1 原子操作 原子操作是指在执行过程中不会被线程调度机制中断的操作。C11在`<stdatomic.h>`(或`<stdatomic>`)头文件中定义了原子类型及其操作,如`_Atomic`类型说明符和一系列原子操作函数(如`atomic_load`、`atomic_store`、`atomic_fetch_add`等)。 ##### 3.2 线程支持(可选) C11标准定义了`<threads.h>`头文件,该头文件提供了一套简化的线程管理API,包括线程的创建(`thrd_create`)、等待(`thrd_join`)、分离(`thrd_detach`)以及退出(`thrd_exit`)等。然而,由于该特性是可选的,并非所有C11编译器都实现了这一特性。 #### 4. 并发编程的设计模式与最佳实践 - **生产者-消费者模型**:是一种常见的并发设计模式,其中一个或多个生产者线程生成数据,并将其放入一个缓冲区中,而一个或多个消费者线程从缓冲区中取出数据并处理。 - **避免共享数据**:尽可能设计不依赖共享状态的算法和数据结构,或者将共享数据的使用限制在最小范围内。 - **使用锁保护共享资源**:当必须使用共享数据时,通过互斥锁等同步机制确保数据的访问是互斥的。 - **无锁编程**:使用原子操作等技术,尝试实现无需锁同步的并发算法,这可以提高性能但实现复杂。 - **测试与验证**:并发程序往往难以调试,因此充分的测试(包括单元测试、压力测试等)和代码审查尤为重要。 #### 5. 实际案例:使用pthreads实现生产者-消费者模型 下面是一个简单的生产者-消费者模型的实现示例,使用pthreads库。 ```c #include <pthread.h> #include <stdio.h> #include <stdlib.h> #define BUFFER_SIZE 10 int buffer[BUFFER_SIZE]; int count = 0; pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t not_empty = PTHREAD_COND_INITIALIZER; pthread_cond_t not_full = PTHREAD_COND_INITIALIZER; void* producer(void* arg) { for (int i = 0; i < 100; ++i) { pthread_mutex_lock(&lock); while (count == BUFFER_SIZE) { pthread_cond_wait(¬_full, &lock); } buffer[count] = i; ++count; pthread_cond_signal(¬_empty); pthread_mutex_unlock(&lock); } return NULL; } void* consumer(void* arg) { for (int i = 0; i < 100; ++i) { pthread_mutex_lock(&lock); while (count == 0) { pthread_cond_wait(¬_empty, &lock); } int item = buffer[--count]; printf("Consumed %d\n", item); pthread_cond_signal(¬_full); pthread_mutex_unlock(&lock); } return NULL; } int main() { pthread_t prod_tid, cons_tid; pthread_create(&prod_tid, NULL, producer, NULL); pthread_create(&cons_tid, NULL, consumer, NULL); pthread_join(prod_tid, NULL); pthread_join(cons_tid, NULL); return 0; } ``` 此示例展示了如何使用pthreads中的互斥锁和条件变量来实现基本的生产者-消费者同步。 #### 6. 结论 C语言通过pthreads等第三方库以及C11及更高版本标准库中的原子操作和线程支持,为并发编程提供了强大的工具。掌握这些基础知识和工具,可以帮助开发者构建高效、可靠的多线程程序。然而,并发编程也带来了许多挑战,如数据竞争、死锁等问题,需要开发者在设计和实现时仔细考虑和测试。
上一篇:
11|标准库:非本地跳转与可变参数是怎样实现的?
下一篇:
13|标准库:如何使用互斥量等技术协调线程运行?
该分类下的相关小册推荐:
c++零基础入门