C 语言多线程编程:并行处理的利剑

本文涉及的产品
无影云电脑企业版,4核8GB 120小时 1个月
无影云电脑个人版,1个月黄金款+200核时
简介: C语言多线程编程是实现并行处理的强大工具,通过创建和管理多个线程,可以显著提升程序执行效率,尤其在处理大量数据或复杂计算时效果显著。

在当今计算机硬件多核架构成为主流的时代,C语言的多线程编程愈发凸显其关键价值。犹如为程序装上了多个强劲的“引擎”,多线程能够让不同的代码片段在同一进程的不同执行流中并发运行,充分挖掘多核处理器的潜力,极大提升程序的执行效率、响应速度以及资源利用率,在诸如网络服务器处理并发请求、图形渲染加速、实时数据处理系统等众多领域,发挥着不可替代的“主力军”作用。

一、线程基础概念与创建

在C语言中,线程是进程内部独立的执行路径,共享进程的地址空间、资源,如全局变量、堆内存等,但拥有自己独立的栈空间用于存储局部变量、函数调用信息等。要开启多线程之旅,首先需引入<pthread.h>头文件,借助pthread_create函数来“点燃”新线程的“导火索”,其函数原型为int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);

这里,pthread_t类型的变量用于标识新创建的线程,thread参数便是用于存储这个标识;attr指向线程属性结构体,若传NULL则采用默认属性;start_routine是一个函数指针,指向新线程启动后要执行的函数,该函数接收一个void *类型参数并返回void *类型结果;arg便是传递给start_routine函数的参数。以下是一个简单示例,创建一个线程打印数字:

#include <stdio.h>
#include <pthread.h>

// 新线程要执行的函数
void *print_numbers(void *arg) {
   
    for (int i = 0; i < 10; i++) {
   
        printf("Thread: %d\n", i);
    }
    return NULL;
}

int main() {
   
    pthread_t thread_id;
    int result = pthread_create(&thread_id, NULL, print_numbers, NULL);
    if (result!= 0) {
   
        printf("线程创建失败!\n");
        return 1;
    }
    // 主线程继续执行其他任务,这里简单打印主线程标识
    printf("Main Thread is running\n");
    // 等待新线程结束,避免主线程提前退出导致程序异常
    pthread_join(thread_id, NULL);
    return 0;
}

在上述代码中,print_numbers函数作为新线程的执行逻辑,循环打印数字,主线程创建新线程后,继续自身执行路径并最终等待新线程结束(通过pthread_join函数),确保整个程序逻辑完整、稳定。

二、线程同步:守护共享资源“安全区”

多线程虽活力满满、效率拔群,但共享进程资源也埋下了隐患,若多个线程同时读写同一共享变量,极易引发数据不一致、竞争条件等问题。为化解这类危机,线程同步机制应运而生,互斥锁(pthread_mutex_t)便是其中“防卫先锋”。

互斥锁的使用遵循“加锁 - 访问共享资源 - 解锁”流程,同一时刻仅有持有锁的线程可访问被保护资源。初始化互斥锁可用pthread_mutex_init函数,pthread_mutex_lock用于加锁,阻塞其他试图加锁线程,pthread_mutex_unlock解锁释放资源。例如,多个线程对共享计数器进行自增操作:

#include <stdio.h>
#include <pthread.h>

// 共享计数器
int counter = 0;
// 定义互斥锁
pthread_mutex_t mutex;

// 线程执行函数,对计数器自增
void *increment_counter(void *arg) {
   
    for (int i = 0; i < 10000; i++) {
   
        pthread_mutex_lock(&mutex);
        counter++;
        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}

int main() {
   
    pthread_t threads[5];
    // 初始化互斥锁
    pthread_mutex_init(&mutex, NULL);
    for (int i = 0; i < 5; i++) {
   
        pthread_create(&threads[i], NULL, increment_counter, NULL);
    }
    for (int i = 0; i < 5; i++) {
   
        pthread_join(threads[i], NULL);
    }
    // 销毁互斥锁,释放资源
    pthread_mutex_destroy(&mutex);
    printf("最终计数器值:%d\n", counter);
    return 0;
}

这段代码创建5个线程对counter自增,借助互斥锁确保每次只有一个线程能修改counter,避免数据混乱,最终输出正确结果。除互斥锁外,还有条件变量(pthread_cond_t),用于线程间基于特定条件的同步通信,比如生产者 - 消费者模型中,生产者生产满库存后通知消费者消费,借助条件变量可精准把控线程协作节奏。

三、线程间通信:编织协作“信息网”

除同步守护共享资源,线程间还需高效通信传递信息、协同工作。消息队列是一种常用通信方式,虽C标准库无内置实现,但借助系统调用(如msgsndmsgrcv函数,不同操作系统实现略有差异)可搭建。以简单模拟数据处理流水线为例,一个线程负责采集数据放入队列,另一个线程从队列取数据处理:

#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

// 消息结构体,契合消息队列格式要求
struct msgbuf {
   
    long mtype;
    int data;
} message;

// 采集数据线程函数
void *produce_data(void *arg) {
   
    int msgq_id = *(int *)arg;
    for (int i = 0; i < 10; i++) {
   
        message.mtype = 1;
        message.data = i;
        if (msgsnd(msgq_id, &message, sizeof(message.data), 0) == -1) {
   
            printf("消息发送失败!\n");
        }
    }
    return NULL;
}

// 处理数据线程函数
void *consume_data(void *arg) {
   
    int msgq_id = *(int *)arg;
    for (int i = 0; i < 10; i++) {
   
        if (msgrcv(msgq_id, &message, sizeof(message.data), 1, 0) == -1) {
   
            printf("消息接收失败!\n");
        } else {
   
            printf("处理数据:%d\n", message.data);
        }
    }
    return NULL;
}

int main() {
   
    pthread_t producer_thread, consumer_thread;
    int msgq_id = msgget(IPC_PRIVATE, 0666);
    if (msgq_id == -1) {
   
        printf("消息队列创建失败!\n");
        return 1;
    }
    int *msgq_ptr = &msgq_id;
    pthread_create(&producer_thread, NULL, produce_data, msgq_ptr);
    pthread_create(&consumer_thread, NULL, consume_data, msgq_ptr);
    pthread_join(producer_thread, NULL);
    pthread_join(consumer_thread, NULL);
    // 删除消息队列,释放资源
    if (msgctl(msgq_id, IPC_RMID, NULL) == -1) {
   
        printf("消息队列删除失败!\n");
    }
    return 0;
}

此例利用消息队列实现两线程数据交互,生产者填充数据,消费者按需取用,高效协作,彰显线程通信价值,优化复杂任务分工流程。

四、多线程编程挑战与应对策略

多线程编程并非一路坦途,在享受并行优势时,也面临诸多挑战。除前述共享资源同步问题,还包括死锁风险,当多个线程相互等待对方释放锁资源时,程序陷入僵局。预防死锁需合理规划锁申请顺序、避免嵌套锁过度使用,或借助超时机制打破僵持。性能调优也是难题,线程创建、切换、同步操作都有开销,需依据硬件资源、任务特性精细权衡线程数量、负载均衡,在计算密集型与I/O密集型任务搭配上优化组合,确保多线程“引擎”马力全开,平稳高效驱动程序在多核舞台“飞驰”,攻克复杂编程场景难关。

C语言多线程编程手握并行处理“利剑”,从基础线程创建、共享资源守护,到灵活通信协作,深挖多核潜能,虽征途有荆棘,但只要巧妙应对挑战,便能在多领域铸就高效、稳定、智能的程序“堡垒”,顺应计算机架构演进浪潮。

相关文章
|
4天前
|
人工智能 自动驾驶 大数据
预告 | 阿里云邀您参加2024中国生成式AI大会上海站,马上报名
大会以“智能跃进 创造无限”为主题,设置主会场峰会、分会场研讨会及展览区,聚焦大模型、AI Infra等热点议题。阿里云智算集群产品解决方案负责人丛培岩将出席并发表《高性能智算集群设计思考与实践》主题演讲。观众报名现已开放。
|
20天前
|
存储 人工智能 弹性计算
阿里云弹性计算_加速计算专场精华概览 | 2024云栖大会回顾
2024年9月19-21日,2024云栖大会在杭州云栖小镇举行,阿里云智能集团资深技术专家、异构计算产品技术负责人王超等多位产品、技术专家,共同带来了题为《AI Infra的前沿技术与应用实践》的专场session。本次专场重点介绍了阿里云AI Infra 产品架构与技术能力,及用户如何使用阿里云灵骏产品进行AI大模型开发、训练和应用。围绕当下大模型训练和推理的技术难点,专家们分享了如何在阿里云上实现稳定、高效、经济的大模型训练,并通过多个客户案例展示了云上大模型训练的显著优势。
|
24天前
|
存储 人工智能 调度
阿里云吴结生:高性能计算持续创新,响应数据+AI时代的多元化负载需求
在数字化转型的大潮中,每家公司都在积极探索如何利用数据驱动业务增长,而AI技术的快速发展更是加速了这一进程。
|
15天前
|
并行计算 前端开发 物联网
全网首发!真·从0到1!万字长文带你入门Qwen2.5-Coder——介绍、体验、本地部署及简单微调
2024年11月12日,阿里云通义大模型团队正式开源通义千问代码模型全系列,包括6款Qwen2.5-Coder模型,每个规模包含Base和Instruct两个版本。其中32B尺寸的旗舰代码模型在多项基准评测中取得开源最佳成绩,成为全球最强开源代码模型,多项关键能力超越GPT-4o。Qwen2.5-Coder具备强大、多样和实用等优点,通过持续训练,结合源代码、文本代码混合数据及合成数据,显著提升了代码生成、推理和修复等核心任务的性能。此外,该模型还支持多种编程语言,并在人类偏好对齐方面表现出色。本文为周周的奇妙编程原创,阿里云社区首发,未经同意不得转载。
11538 10
|
9天前
|
人工智能 自然语言处理 前端开发
100个降噪蓝牙耳机免费领,用通义灵码从 0 开始打造一个完整APP
打开手机,录制下你完成的代码效果,发布到你的社交媒体,前 100 个@玺哥超Carry、@通义灵码的粉丝,可以免费获得一个降噪蓝牙耳机。
3971 13
|
16天前
|
人工智能 自然语言处理 前端开发
用通义灵码,从 0 开始打造一个完整APP,无需编程经验就可以完成
通义灵码携手科技博主@玺哥超carry 打造全网第一个完整的、面向普通人的自然语言编程教程。完全使用 AI,再配合简单易懂的方法,只要你会打字,就能真正做出一个完整的应用。本教程完全免费,而且为大家准备了 100 个降噪蓝牙耳机,送给前 100 个完成的粉丝。获奖的方式非常简单,只要你跟着教程完成第一课的内容就能获得。
6638 10
|
27天前
|
缓存 监控 Linux
Python 实时获取Linux服务器信息
Python 实时获取Linux服务器信息
|
13天前
|
人工智能 自然语言处理 前端开发
什么?!通义千问也可以在线开发应用了?!
阿里巴巴推出的通义千问,是一个超大规模语言模型,旨在高效处理信息和生成创意内容。它不仅能在创意文案、办公助理、学习助手等领域提供丰富交互体验,还支持定制化解决方案。近日,通义千问推出代码模式,基于Qwen2.5-Coder模型,用户即使不懂编程也能用自然语言生成应用,如个人简历、2048小游戏等。该模式通过预置模板和灵活的自定义选项,极大简化了应用开发过程,助力用户快速实现创意。
|
2天前
|
机器学习/深度学习 人工智能 安全
通义千问开源的QwQ模型,一个会思考的AI,百炼邀您第一时间体验
Qwen团队推出新成员QwQ-32B-Preview,专注于增强AI推理能力。通过深入探索和试验,该模型在数学和编程领域展现了卓越的理解力,但仍在学习和完善中。目前,QwQ-32B-Preview已上线阿里云百炼平台,提供免费体验。
|
10天前
|
人工智能 C++ iOS开发
ollama + qwen2.5-coder + VS Code + Continue 实现本地AI 辅助写代码
本文介绍在Apple M4 MacOS环境下搭建Ollama和qwen2.5-coder模型的过程。首先通过官网或Brew安装Ollama,然后下载qwen2.5-coder模型,可通过终端命令`ollama run qwen2.5-coder`启动模型进行测试。最后,在VS Code中安装Continue插件,并配置qwen2.5-coder模型用于代码开发辅助。
689 4