首页 后端开发 C++ Rust 线​​程安全性:与 C 的比较。

Rust 线​​程安全性:与 C 的比较。

Nov 19, 2024 am 11:54 AM

在这个POC(概念证明)中,我们将探索Rust语言如何处理竞争条件,并将其与C ,一种广泛使用的语言,但竞争的安全保障较少。

Rust 线​​程安全性:与 C 的比较

线程安全:从 C 到 Rust 的数据竞争

指数

    一、简介
  • 2. 线程
  • 3. C 语言的实现
    • 3.1.没有针对竞争条件的保护的代码
    • 3.2.使用互斥体修复
  • 4. Rust 中的实现
    • 4.1.竞争条件问题
    • 4.2.互斥体和弧的解析
    • 4.3.互斥体对比读写锁
  • 5. 结论
  • 6. 参考文献

一、简介

在计算中,

线程用于将软件任务划分为可以并发执行的子任务。通过使用线程,我们获得了处理时间并更好地利用机器的资源,但这种竞争带来了挑战,例如竞争条件,这可能会产生数据的严重不一致。


2. 线程

线程是允许您同时处理任务的执行单元。我们可以将线程视为程序内独立的执行流,如下图所示:

Rust Threads safety: Uma comparação com C.

虽然线程带来了性能优势,但它们也带来了风险,尤其是在访问共享资源时。

此外,线程还可以用来实现并行性,即多个任务在不同的CPU核心上同时执行。这使得程序能够更好地利用可用的硬件,加快独立任务的执行速度。


3. C 语言的实现

让我们在

C 中创建一个简单的系统:

    初始余额为 1000。
  1. 一组可以是贷方或借方的交易。
  2. 使用线程并行处理这些事务。
3.1.没有针对竞争条件的保护的代码

int saldo = 1000; 

void creditar(int valor) {
    int tmp_saldo = saldo;

    sleep(1); // Delay simulado

    saldo += tmp_saldo + valor;
}

void debitar(int valor) {
    int temp = saldo;

    sleep(1); // Delay simulado

    if (temp >= valor) {
        saldo = temp - valor;
    }
}

void* processar_transacao(void* arg) {
    int valor = *(int*)arg;

    if (valor > 0) {
        creditar(valor);
    } else {
        debitar(abs(valor));
    }

    return NULL;
}

int main() {
    int transactions[] = {100, -50, 200, -150, 300, -200, 150, -100, 50, -50};
    int num_transactions = sizeof(transactions) / sizeof(transactions[0]);

    pthread_t threads[num_transactions];

    for (int i = 0; i < num_transactions; i++) {
        pthread_create(&threads[i], NULL, processar_transacao, &transactions[i]); // Cria uma thread para cada transação
    }

    for (int i = 0; i < num_transactions; i++) {
        pthread_join(threads[i], NULL); // Aguarda todas as threads terminarem
    }

    printf("Saldo final da conta: %d\n", saldo);
    return 0;
}
登录后复制
登录后复制
当我们选择具有

多线程处理的环境时,我们所说的竞争条件可能会发生,当两个线程访问并修改相同的值时,我们就会出现竞争条件。出现此问题的原因是,由于调用之间的竞争,无法保证每个线程中访问的值的同步。

多次执行此代码时,最终余额会有所不同,因为线程同时访问和更改余额。

Rust Threads safety: Uma comparação com C.


3.2.使用互斥体修复

int saldo = 1000; 

void creditar(int valor) {
    int tmp_saldo = saldo;

    sleep(1); // Delay simulado

    saldo += tmp_saldo + valor;
}

void debitar(int valor) {
    int temp = saldo;

    sleep(1); // Delay simulado

    if (temp >= valor) {
        saldo = temp - valor;
    }
}

void* processar_transacao(void* arg) {
    int valor = *(int*)arg;

    if (valor > 0) {
        creditar(valor);
    } else {
        debitar(abs(valor));
    }

    return NULL;
}

int main() {
    int transactions[] = {100, -50, 200, -150, 300, -200, 150, -100, 50, -50};
    int num_transactions = sizeof(transactions) / sizeof(transactions[0]);

    pthread_t threads[num_transactions];

    for (int i = 0; i < num_transactions; i++) {
        pthread_create(&threads[i], NULL, processar_transacao, &transactions[i]); // Cria uma thread para cada transação
    }

    for (int i = 0; i < num_transactions; i++) {
        pthread_join(threads[i], NULL); // Aguarda todas as threads terminarem
    }

    printf("Saldo final da conta: %d\n", saldo);
    return 0;
}
登录后复制
登录后复制

互斥体是一种同步原语,可确保一次只有一个线程可以访问共享资源。缩写词互斥体来自英文术语互斥,意思是“互斥”。

当一个线程获取互斥体时,任何其他尝试获取相同互斥体的线程都会被挂起,直到第一个线程释放互斥体。这可以防止两个或多个进程(线程)同时访问共享资源。

Rust Threads safety: Uma comparação com C.

4. Rust 中的实现

int saldo = 1000; 
pthread_mutex_t saldo_mutex; // Mutex para proteger o saldo

void creditar(int valor) { 
    pthread_mutex_lock(&saldo_mutex); // Bloqueia o mutex
    int tmp_saldo = saldo;

    sleep(1); // Delay simulado

    saldo = tmp_saldo + valor;

    pthread_mutex_unlock(&saldo_mutex); // Libera o mutex
}

void debitar(int valor) {
    pthread_mutex_lock(&saldo_mutex); // Bloqueia o mutex
    int tmp_saldo = saldo;

    sleep(1); // Delay simulado

    if (tmp_saldo >= valor) {
        saldo = tmp_saldo - valor;
    }

    pthread_mutex_unlock(&saldo_mutex);  // Libera o mutex
}
登录后复制

将 Rust 视为一种不存在于数据竞赛中的语言并不高效,但我们可以理解 结构 及其编译器如何通过为内存和线程安全带来出色的功能来做出贡献。

Rust 使用 所有权借用 和并发安全结构等功能,通过编译时保证来对待竞争条件

  • Arc:安全共享不可变数据。
  • MutexRwLock:可变数据的访问控制。

4.1.竞争条件问题

不使用 Arc 和 Mutex 结构

Rust’s rich type system and ownership model guarantee memory-safety and thread-safety — enabling you to eliminate many classes of bugs at compile-time.
登录后复制

Rust 不允许在没有保护的情况下从多个线程直接访问可变数据(余额)。
编译器将生成错误,因为余额在没有安全机制的情况下被移动到多个线程(handle1handle2)。
将显示的错误消息是:

fn main() {
    let mut saldo = 1000; // saldo mutável, mas sem proteção

    let handle1 = thread::spawn(move || {
        saldo += 100;  // erro: `saldo` é movido para esta thread sem proteção
    });

    let handle2 = thread::spawn(move || {
        saldo -= 50;  // erro: `saldo` é movido para esta thread sem proteção
    });

    handle1.join().unwrap();
    handle2.join().unwrap();
}
登录后复制

4.2.互斥体和弧的解析

使用 Mutex 和 Arc,我们能够编译并执行我们的代码,并解决了竞争条件问题。

error[E0382]: use of moved value: `saldo`
登录后复制

4.3.互斥体对比读写锁

Mutex 和 RwLock 用于处理竞争条件,各自具有特定的优点:

互斥体:保证一个线程对资源的独占访问,阻止对其他线程的访问,直到该线程被释放。它简单而有效,但即使是读取也会阻塞资源,从而在读取密集的场景中效率较低

RwLock:使用 .read() 允许多个同时读取,并使用 .write() 限制独占写入。它非常适合以读取为主的场景,因为它通过允许读取操作中的并行性来提高性能。


5. 结论

C 和 Rust 之间的比较突出了解决竞争条件的不同方法。 C 需要注意避免竞争条件错误,而 Rust 除了所有权模型之外还通过 Mutex、RwLock 和 Arc 等工具在编译时降低了这些风险。这不仅使代码更加安全,还通过避免无声错误减少了程序员的心理负担

总之,Rust 将自己定位为开发竞争系统的绝佳选择,提供安全性和可靠性。


6. 参考文献

  • 带有代码的仓库:https://github.com/z4nder/rust-data-races
  • https://en.wikipedia.org/wiki/Race_condition
  • https://blog.bughunt.com.br/o-que-sao-vulnerabilidades-race-condition/
  • https://medium.com/cwi-software/spring-boot-race-condition-e-ambiente-multi-thread-263b21e0042e
  • https://learn.microsoft.com/en-us/troubleshoot/developer/visualstudio/visual-basic/language-compilers/race-conditions-deadlocks
  • https://www.reddit.com/r/rust/comments/18faxjg/understanding_threadsafety_vs_race_conditions/?rdt=52263
  • https://doc.rust-lang.org/nomicon/races.html
  • https://news.ycombinator.com/item?id=23599598

以上是Rust 线​​程安全性:与 C 的比较。的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Java教程
1677
14
CakePHP 教程
1431
52
Laravel 教程
1334
25
PHP教程
1280
29
C# 教程
1257
24
C#与C:历史,进化和未来前景 C#与C:历史,进化和未来前景 Apr 19, 2025 am 12:07 AM

C#和C 的历史与演变各有特色,未来前景也不同。1.C 由BjarneStroustrup在1983年发明,旨在将面向对象编程引入C语言,其演变历程包括多次标准化,如C 11引入auto关键字和lambda表达式,C 20引入概念和协程,未来将专注于性能和系统级编程。2.C#由微软在2000年发布,结合C 和Java的优点,其演变注重简洁性和生产力,如C#2.0引入泛型,C#5.0引入异步编程,未来将专注于开发者的生产力和云计算。

C#vs. C:学习曲线和开发人员的经验 C#vs. C:学习曲线和开发人员的经验 Apr 18, 2025 am 12:13 AM

C#和C 的学习曲线和开发者体验有显着差异。 1)C#的学习曲线较平缓,适合快速开发和企业级应用。 2)C 的学习曲线较陡峭,适用于高性能和低级控制的场景。

什么是C  中的静态分析? 什么是C 中的静态分析? Apr 28, 2025 pm 09:09 PM

静态分析在C 中的应用主要包括发现内存管理问题、检查代码逻辑错误和提高代码安全性。1)静态分析可以识别内存泄漏、双重释放和未初始化指针等问题。2)它能检测未使用变量、死代码和逻辑矛盾。3)静态分析工具如Coverity能发现缓冲区溢出、整数溢出和不安全API调用,提升代码安全性。

C和XML:探索关系和支持 C和XML:探索关系和支持 Apr 21, 2025 am 12:02 AM

C 通过第三方库(如TinyXML、Pugixml、Xerces-C )与XML交互。1)使用库解析XML文件,将其转换为C 可处理的数据结构。2)生成XML时,将C 数据结构转换为XML格式。3)在实际应用中,XML常用于配置文件和数据交换,提升开发效率。

C  中的chrono库如何使用? C 中的chrono库如何使用? Apr 28, 2025 pm 10:18 PM

使用C 中的chrono库可以让你更加精确地控制时间和时间间隔,让我们来探讨一下这个库的魅力所在吧。C 的chrono库是标准库的一部分,它提供了一种现代化的方式来处理时间和时间间隔。对于那些曾经饱受time.h和ctime折磨的程序员来说,chrono无疑是一个福音。它不仅提高了代码的可读性和可维护性,还提供了更高的精度和灵活性。让我们从基础开始,chrono库主要包括以下几个关键组件:std::chrono::system_clock:表示系统时钟,用于获取当前时间。std::chron

C的未来:改编和创新 C的未来:改编和创新 Apr 27, 2025 am 12:25 AM

C 的未来将专注于并行计算、安全性、模块化和AI/机器学习领域:1)并行计算将通过协程等特性得到增强;2)安全性将通过更严格的类型检查和内存管理机制提升;3)模块化将简化代码组织和编译;4)AI和机器学习将促使C 适应新需求,如数值计算和GPU编程支持。

C:死亡还是简单地发展? C:死亡还是简单地发展? Apr 24, 2025 am 12:13 AM

1)c relevantduetoItsAverity and效率和效果临界。2)theLanguageIsconTinuellyUped,withc 20introducingFeaturesFeaturesLikeTuresLikeSlikeModeLeslikeMeSandIntIneStoImproutiMimproutimprouteverusabilityandperformance.3)

如何理解C  中的DMA操作? 如何理解C 中的DMA操作? Apr 28, 2025 pm 10:09 PM

DMA在C 中是指DirectMemoryAccess,直接内存访问技术,允许硬件设备直接与内存进行数据传输,不需要CPU干预。1)DMA操作高度依赖于硬件设备和驱动程序,实现方式因系统而异。2)直接访问内存可能带来安全风险,需确保代码的正确性和安全性。3)DMA可提高性能,但使用不当可能导致系统性能下降。通过实践和学习,可以掌握DMA的使用技巧,在高速数据传输和实时信号处理等场景中发挥其最大效能。

See all articles