当前位置:首页 > 技术 > 正文内容

Linux多线程编程基础:栈、TLS、互斥锁与条件变量解析

访客 技术 2026年5月30日 1
Linux多线程编程对于提升程序效率至关重要,尤其是在服务器、游戏开发和数据处理等领域。本文将介绍如何使用POSIX Threads(需包含``头文件)进行多线程编程,重点讲解线程栈、TLS(线程局部存储)、互斥锁和条件变量。

1. 线程栈(Thread Stack)

每个线程拥有独立的栈空间,用于存放局部变量和函数调用帧等信息。默认情况下,子线程的栈大小为2MB,可以通过系统命令`ulimit -s`查看。
#include 
#include 

void* thread_routine(void* arg) {
    int local_data = 50; // 存储在栈上的局部变量
    printf("Thread ID: %lu, Local Data: %d\n", pthread_self(), local_data);
    return NULL;
}

int main() {
    pthread_t thread_id;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setstacksize(&attr, 2 * 1024 * 1024); // 设置2MB栈大小

    pthread_create(&thread_id, &attr, thread_routine, NULL);
    pthread_join(thread_id, NULL);

    pthread_attr_destroy(&attr);
    return 0;
}

2. TLS(Thread Local Storage)

TLS允许每个线程拥有自己的"全局"变量副本,避免了共享变量带来的竞争问题。可以使用`__thread`关键字或者`pthread_key_t`来实现。
#include 
#include 
#include 

pthread_key_t tls_key;

void cleanup(void* ptr) {
    printf("Thread %lu: Releasing resource at %p\n", pthread_self(), ptr);
    free(ptr);
}

void* thread_function(void* arg) {
    int* private_data = malloc(sizeof(int));
    *private_data = (int)(long)arg;
    pthread_setspecific(tls_key, private_data);

    printf("Thread %lu: Private Data: %d\n", pthread_self(), *(int*)pthread_getspecific(tls_key));
    return NULL;
}

int main() {
    pthread_key_create(&tls_key, cleanup);

    pthread_t thread1, thread2;
    pthread_create(&thread1, NULL, thread_function, (void*)1);
    pthread_create(&thread2, NULL, thread_function, (void*)2);

    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    pthread_key_delete(tls_key);
    return 0;
}

3. 互斥锁(Mutex)

互斥锁确保同一时刻只有一个线程能够访问共享资源,防止数据竞争。
#include 
#include 

pthread_mutex_t lock;
int shared_counter = 0;

void* increment_counter(void* arg) {
    for (int i = 0; i < 100000; ++i) {
        pthread_mutex_lock(&lock);
        ++shared_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);

    printf("Final Counter Value: %d\n", shared_counter);
    pthread_mutex_destroy(&lock);
    return 0;
}

4. 条件变量(Condition Variable)

条件变量用于线程间的同步,通常与互斥锁配合使用。
#include 
#include 
#include 

pthread_mutex_t mtx;
pthread_cond_t cv;
int ready_flag = 0;

void* producer(void* arg) {
    pthread_mutex_lock(&mtx);
    ready_flag = 1;
    printf("Producer: Resource is ready.\n");
    pthread_cond_signal(&cv);
    pthread_mutex_unlock(&mtx);
    return NULL;
}

void* consumer(void* arg) {
    pthread_mutex_lock(&mtx);
    while (!ready_flag) {
        pthread_cond_wait(&cv, &mtx);
    }
    printf("Consumer: Resource acquired.\n");
    pthread_mutex_unlock(&mtx);
    return NULL;
}

int main() {
    pthread_mutex_init(&mtx, NULL);
    pthread_cond_init(&cv, NULL);

    pthread_t prod, cons;
    pthread_create(&cons, NULL, consumer, NULL);
    sleep(1);
    pthread_create(&prod, NULL, producer, NULL);

    pthread_join(prod, NULL);
    pthread_join(cons, NULL);

    pthread_mutex_destroy(&mtx);
    pthread_cond_destroy(&cv);
    return 0;
}

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。