C语言多线程编程:从入门到精通,一篇文章彻底搞懂

C语言多线程编程:从入门到精通,一篇文章彻底搞懂

关注、星标公众号,直达精彩内容

正文一、多线程基础概念1. 什么是线程?线程是程序执行的最小单元,是进程中的一个独立执行路径。一个进程可以包含多个线程,这些线程共享进程的内存空间(如全局变量、堆内存),但每个线程有自己的栈空间(用于存储局部变量和函数调用信息)。

2. 线程与进程的区别特性

进程

线程

内存空间

独立的内存空间

共享进程的内存空间

资源开销

创建和销毁成本高

创建和销毁成本低

通信方式

需要进程间通信(IPC)

直接共享内存,通信更高效

上下文切换

切换成本高

切换成本低

稳定性

一个进程崩溃不会影响其他进程

一个线程崩溃可能导致整个进程崩溃

3. 为什么使用多线程?提高程序响应速度:例如在GUI程序中,主线程处理界面,子线程处理耗时任务。充分利用多核CPU:多线程可以并行执行,提升计算效率。简化复杂任务的开发:将任务分解为多个线程,逻辑更清晰。二、C语言多线程实现(POSIX线程库)1. POSIX线程库简介C语言本身不直接支持多线程,但通过POSIX线程库(pthread)可以实现多线程编程。该库是跨平台的,主要在Linux/Unix系统中使用,Windows下需使用Win32 API(本文以pthread为例)。

2. 基本函数函数

作用

pthread_create()

创建线程

pthread_join()

等待线程结束

pthread_exit()

终止当前线程

pthread_detach()

将线程设为分离状态(无需等待)

pthread_mutex_lock()

加锁(保护共享资源)

pthread_mutex_unlock()

解锁

pthread_cond_wait()

条件变量等待

pthread_cond_signal()

唤醒等待的线程

三、多线程编程入门示例1. 创建线程代码语言:javascript复制#include

#include

// 线程执行函数

void* thread_function(void* arg) {

int value = *(int*)arg;

printf("Hello from thread! Value: %d\n", value);

return NULL;

}

int main() {

pthread_t thread; // 定义线程标识符

int arg = 42; // 传递给线程的参数

// 创建线程

if (pthread_create(&thread, NULL, thread_function, &arg) != 0) {

perror("Failed to create thread");

return 1;

}

// 等待线程结束

pthread_join(thread, NULL);

printf("Main thread finished.\n");

return 0;

}

编译命令:

代码语言:javascript复制gcc -o thread_example thread_example.c -lpthread

运行结果:

代码语言:javascript复制Hello from thread! Value: 42

Main thread finished.

imageimage

2. 线程生命周期创建:pthread_create()运行:线程执行指定函数等待:pthread_join() 等待线程结束分离:pthread_detach() 释放线程资源终止:pthread_exit() 或线程函数返回四、线程同步机制1. 共享资源与数据竞争当多个线程同时访问共享资源(如全局变量)时,可能导致数据不一致。例如:

代码语言:javascript复制#include

#include

int counter = 0;

void* increment_counter(void* arg) {

for (int i = 0; i < 100000; i++) {

counter++; // 未保护的共享资源

}

return NULL;

}

int main() {

pthread_t t1, t2;

pthread_create(&t1, NULL, increment_counter, NULL);

pthread_create(&t2, NULL, increment_counter, NULL);

pthread_join(t1, NULL);

pthread_join(t2, NULL);

printf("Final counter value: %d\n", counter); // 预期值为200000,但实际可能小于该值

return 0;

}

imageimage

问题:counter++ 是非原子操作(读取-修改-写入),多个线程同时操作会导致数据竞争。

2. 互斥锁(Mutex)互斥锁用于保护共享资源,确保同一时刻只有一个线程访问。

代码语言:javascript复制#include

#include

int counter = 0;

pthread_mutex_t lock; // 定义互斥锁

void* increment_counter(void* arg) {

for (int i = 0; i < 100000; i++) {

pthread_mutex_lock(&lock); // 加锁

counter++;

pthread_mutex_unlock(&lock); // 解锁

}

return NULL;

}

int main() {

pthread_mutex_init(&lock, NULL); // 初始化互斥锁

pthread_t t1, t2;

pthread_create(&t1, NULL, increment_counter, NULL);

pthread_create(&t2, NULL, increment_counter, NULL);

pthread_join(t1, NULL);

pthread_join(t2, NULL);

pthread_mutex_destroy(&lock); // 销毁互斥锁

printf("Final counter value: %d\n", counter); // 输出200000

return 0;

}

imageimage

3. 条件变量(Condition Variable)条件变量用于线程间通信,当某个条件满足时唤醒等待的线程。

示例:生产者-消费者模型

代码语言:javascript复制#include

#include

#include

#define BUFFER_SIZE 5

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 = 1; i <= 10; i++) {

pthread_mutex_lock(&lock);

while (count == BUFFER_SIZE) {

pthread_cond_wait(¬_full, &lock); // 缓冲区满时等待

}

buffer[count++] = i;

printf("Produced: %d\n", i);

pthread_cond_signal(¬_empty); // 通知消费者

pthread_mutex_unlock(&lock);

usleep(100000); // 模拟生产时间

}

return NULL;

}

void* consumer(void* arg) {

for (int i = 1; i <= 10; 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);

usleep(100000); // 模拟消费时间

}

return NULL;

}

int main() {

pthread_t p, c;

pthread_create(&p, NULL, producer, NULL);

pthread_create(&c, NULL, consumer, NULL);

pthread_join(p, NULL);

pthread_join(c, NULL);

return 0;

}

imageimage

‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧ END ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧

代码语言:javascript复制关注我的微信公众号,回复“C语言”免费领取300G编程资料。代码语言:javascript复制欢迎点赞、分享、推荐、留言。

相关内容

生产主管日常工作事项
手游365

生产主管日常工作事项

⌚ 12-17 👁️‍🗨️ 7484
8款最佳电脑显示器排行榜
365bet登录

8款最佳电脑显示器排行榜

⌚ 07-12 👁️‍🗨️ 1304
梦幻西游在哪摆摊卖宝宝,摆摊卖宝宝位置
手游365

梦幻西游在哪摆摊卖宝宝,摆摊卖宝宝位置

⌚ 07-22 👁️‍🗨️ 9667

友情链接