当前位置:首页 >> 内饰

Rust 和 C++ 的并发纳,傻傻分不清楚?

来源:内饰   2023年04月07日 12:15

由于Rust当前数透过自然数的化学键连续性,未任何去除,因此这个变动与Rust无关。

但是,带有compare_exchange法则的Atomic议案需咨询如何可执行去除,并且不该召集这个议案的对此。

Compare-exchange的线程排序

在C++ 11中所,compare_exchange线性立即比起成功的线程排序至少很难弱于惨败的线程排序。不遵从compare_exchange(…, …, memory_order_release, memory_order_acquire)。Rust的compare_exchange线性比起最简单地镜像了这个立即。

P0418R2认为不该作废这个受限,而这个议案将在C++ 17中所发售。

另一方面,Rust 1.64也作废了不尽相同的受限,特地参见rust-lang/rust#98383。

也就是说锁住构造线性constexpr

C++的std::mutex有一个constexpr构造线性,这仅仅它可以在编译器时作为常量评估的一部分来构造。然而,相当是所有的做到都透过了这一点。例如,微软公司的std::mutex做到就不数限于constexpr构造线性。要想编码俱备相容性,就很难忽视这个构造线性。

此外,寻常的是,C++的std::condition_variable和std::shared_mutex究竟未透过constexpr构造线性。

Rust 1.0中所的Mutex不包括const fn new。再加上Rust对一个系统初始化的严格立即,因此很难在一个系统数据类型中所可用Mutex。

这个问题已在Rust 1.63.0(rust-lang/rust#93740)中所给予洞察决:所有Mutex::new、RwLock::new和Condvar::new都是const线性。

latch和barrier

P1135R6在C++ 20中所带入了std::latch和std::barrier。两者都强制继续前进多个虚拟机进发某个点。回事latch就是一个缓冲机内,根据每个虚拟机乘以,直到转变成零。latch只能可用一次。barrier是一个极现职的原版,可以重用,并遵从一个“顺利完成线性”,当缓冲机内翻倍零时则会可执行。

Rust从1.0开始有了十分相似的Barrier连续性。但它的灵感来自pthread (pthread_barrier_t)。

Rust(以及pthread)的barrier不如C++灵活。它只有一个“乘以和继续前进”操写作者(wait),未C++的std::barrier自带的“只有继续前进”、“只有乘以”以及“乘以并丢弃”等特性。

另一方面,与C++各有不同,Rust(以及pthread)的“乘以和继续前进”操写作者都会指定一个虚拟机作为组长,它可以本来“顺利完成线性”(而且意味著不够灵活)。

Rust缺少的操写作者回事可以不对替换成。我们只需重申这些近期的名称。

信号量

P1135R6还在C++ 20中所带入了信号量:std::counting_semaphore和std::binary_semaphore。

Rust未国际标准化组织的信号量连续性,尽管它通过thread::park和unpark为每个虚拟机分配了二进制信号量。

我们可以可用Mutex和Condvar手动重构信号量,但大多数操写作者系统强制可用AtomicU32做到极高效和不够小的信号量。例如,Linux上的futex()和Windows上的WaitOnAddress()。暗示的做到衡量操写作者系统及其原版,以及哪些化学键个数可用以这些操写作者。

C++的counting_semaphore是一个模板,它遵从一个自然数作为表达式,用以传达我们期望总和的数目。例如,counting_semaphore的小数至少为1000,因此可以是16位或不够大。binary_semaphore连续性只是counting_semaphore的原指,在某些SDK上可以是单字节。

Rust还有这种国际标准化组织的连续性。Rust的泛型强制做到了某种某种程度的一致性,因此将常量作为泛型表达式时也都会受到一定的受限。

我们有单独的Semaphore32、Semaphore64等等,但这无论如何有点矫枉过正。Semaphore、Semaphore,甚至是Semaphore固然未什么问题,但在此之前的除此以外托中所并未这些。我们的化学键连续性就是AtomicU32、AtomicU64等等。

如上所述,对于化学键连续性,我们数透过编译器SDK原生赞成的连续性。如果我们将不尽相同的以人为本应用以信号量,它就不都会发挥作用以未futex或WaitOnAddress线性的SDK上,比如macOS。如果我们根据个数建立各有不同的信号量连续性,那么某些个数就不都会出现在(某些原版的)Linux和各种BSD中所了。

如果我们期望Rust建立除此以外的信号量连续性,首先需洞察我们究竟需各有不同个数的信号量,以及灵活性和相容性需翻倍什么某种程度。比如说我们只需一个32位的信号量(可用基于锁住的替代提案),但任何此类的强烈立即都不必包括用例和受限的详述暗示。

化学键继续前进和特地示

P1135R6替换成到C++ 20的另一个原先连续性是化学键wait和notify线性。

这些线性通过除此以外终端,官方网站了Linux上的futex()和Windows上的WaitOnAddress()。

然而,无论操写作者系统赞成什么,所有SDK上的所有个数的化学键都可以可用这两个线性。Linux的futex(在FUTEX2在此之前)是32位的,但C++强制可用atomic::wait。

这回事典型“停车场”:将线程地址映射到锁住和数据流的全局HashMap。这仅仅,Linux上的32位继续前进操写作者可以可用基于futex的做到,而其他个数可用的做到则实际上各有不同。

如果我们遵循只透过原生赞成的连续性和线性的以人为本,就不都会透过这样的做到了。这仅仅,Linux上只有AtomicU32::wait(和AtomicI32::wait),而Windows上所有化学键连续性都包括wait法则。

在Rust中所,有关Atomic*::wait和Atomic*::notify的议案需咨询Rust究竟需溃而采行全局详见。

jthread和stop_token

P0660R10向C++ 20带入了std::jthread和std::stop_token。

暂时无非stop_token不谈,回事jthread只是一个除此以外的std::thread,它都会在销毁时则会被join() 。这可以避免虚拟机意外脱离,并经常性接入。但是,它也带入了一个潜在的原先陷阱:第一时间销毁jthread某类都会立即join虚拟机,致使适配消亡。

Rust从原版1.63.0开始,加入了有线性调用的虚拟机(rust-lang/rust#93203)。就像jthread一样,线性调用虚拟机都会则会join。但是,它们在此之前的的中央很明确,并且是可以忽视的必要必要。此外,借来核对机内确信这种必要必要,强制你必要地借来线性调用虚拟机中所的局部数据类型,只要这些数据类型只在线性调用中所均可。

除了则会join都是,jthreads还有一个配特点,就是stop_token以及对应的stop_source。如果在stop_source上子程序request_stop(),则stop_token上适当的stop_requested()法则都会前往true。我们可以为了让这个法则来恳特地虚拟机暂停,而这一步都会在join在此之前在jthread的析构线性中所则会顺利完成。而核对并暂停token的可执行则由虚拟机的编码顺利完成。

到此前,它看起来就像一个都可的AtomicBool。

回事,二者最大者的不同点在于stop_callback连续性。该连续性强制给暂停令牌注册一个Lua线性,也就是一个“暂停线性”。可用适当的stop_source恳特地暂停就可以可执行该线性。实际上,我们可以为了让这个线性来暂停或作废虚拟机。

在Rust中所,我们可以将十分相似AtomicBool的特性替换成到thread::scope的Scope某类中所。只需一个最简单的线性is_finished(Companyself) -> bool或stop_requested(Companyself) -> bool均可,用以指示配范围线性究竟收尾。然后就可以结合request_stop(Companyself)法则从任何人口众多邮寄恳特地。

stop_callback的特性不够最简单,Rust的无关议案需详述咨询其终端、用例和受限。

化学键浮点运算

P0020R6在C++ 20中所替换成了对化学键浮点平方根和减法的赞成。

在Rust中所替换成AtomicF32或AtomicF64也很难以,但无论如何唯一赞成原生化学键浮点运算的SDK都是一些GPU,但Rust还不赞成。

将这些连续性替换成到Rust的强烈立即不必重申一些引人注目的用例。

化学键按字节线程镜像

现阶段,我们还不能在Rust或C++中所有利于做到遵守线程模型所有规则的多肽锁住。

P1478R7建议在C++中所替换成atomic_load_per_byte_memcpy和atomic_store_per_byte_memcpy来解决这个问题。

对于Rust,我写到了一个议案,期望通过AtomicPerByte连续性来官方网站这个特性:RFC 3301。

化学键shared_ptr

P0718R2在C++ 20中所替换成了atomic和atomic。

提到小数指针(C++中所的shared_ptr,Rust中所的Arc)多用以并作无锁住数据结构。atomic可以特别强调提到小数,从而减低了应该可执行此操写作者的重复性。

在Rust中所,我们可以替换成等效的AtomicArc和AtomicWeak连续性。

然而,C++的shared_ptr可以为null,而在Rust中所则需Option>。现阶段还不清楚AtomicArc究竟可以为null,或者我们究竟不该透过AtomicOptionArc。

流行的arc-swap crate已经在Rust透过了一些变体,但是,据我所知,还未任何强烈立即将十分相似的的路替换成到除此以外托。

synchronized_value

虽然P0290R2重申了一种原是synchronized_value的连续性,它结合了也就是说锁住和T,但最终未被遵从。

虽然未被C++遵从,但这是一个寻常的强烈立即,因为synchronized_value几乎就是Rust中所的Mutex。

在C++中所,std::mutex不包括它庇护所的数据,甚至究竟不明白它庇护所的是什么。这仅仅,用户不必负有责任,记住哪些数据受庇护所以及由哪个也就是说锁住庇护所,并确保每次访问期间“受庇护所”数据时都锁住定应该的也就是说锁住。

在Rust Mutex的所设计中所,MutexGuard的不当典型对T的(高性能)提到,可以透过极高的必要性,同时在只需也就是说锁住的意味著,也可以可用Mutex。synchronized_value的强烈立即是,将此模式替换成到C++,但可用闭包而不是也就是说锁住,因为C++不跟踪休眠。

暗示了

在我看来,Rust可以继续学习C++的专业知识,但我们很难相当需要镜像粘贴C++的期望。正如我们在Mutex、线性调用虚拟机、Atomic*::from_mut中所看到的那样,在透过不尽相同特性时,Rust可以采行实际上各有不同的表现形式。

我们的目标不是透过与C++实际上不尽相同的特性,而不该是透过Rust水体以及除此以外托需的的路,而这意味著与C++用户的需求实际上各有不同。

重庆哪里治疗白癜风最好
多维元素片可以增强抵抗力吗
深圳看牛皮癣去哪个医院好
贵阳妇科去哪看
广西白癜风医院哪家专业好
友情链接