如何通过网站建设吸引客户并有效管理网站建设费用?

摘要:网站建设怎么找到客户,网站建设费无形资产,腾讯云学生怎么做网站的,天津网站优化公司哪家专业用于共享数据保护的替代工具 虽然互斥元是最通用的机制,但提到保护共享数据时,它们并不是
网站建设怎么找到客户,网站建设费 无形资产,腾讯云学生怎么做网站的,天津网站优化公司哪家专业用于共享数据保护的替代工具 虽然互斥元是最通用的机制#xff0c;但提到保护共享数据时#xff0c;它们并不是唯一的选择#xff1b;还有别的替代品#xff0c;可以在特定情况下提供更恰当的保护。 一个特别极端#xff08;但却相当常见#xff09;的情况#xff0c;…用于共享数据保护的替代工具 虽然互斥元是最通用的机制但提到保护共享数据时它们并不是唯一的选择还有别的替代品可以在特定情况下提供更恰当的保护。 一个特别极端但却相当常见的情况就是共享数据只在初始化时才需要并发访问的保护但在那之后却不需要显式同步。这可能是因为数据是一经创建就是只读的所以就不存在可能的同步问题或者是因为必要的保护作为数据上操作的一部分被隐式地执行。在任一情况中在数据被初始化之后锁定互斥元纯粹是为了保护初始化这是不必要的并且对性能会产生的不必要的打击。为了这个原因C标准提供了一种机制纯粹为了在初始化过程中保护共享数据。 在初始化时保护共享数据 假设你有一个构造起来非常昂贵的共享资源只有当实际需要时你才会要这样做。也许它会打开一个数据库连接或分配大量的内存。像这样的延迟初始化lazyinitialization在单线程代码中是很常见的——每个请求资源的操作首先检查它是否已经初始化如果没有就在使用之前初始化之。 std::shared_ptrsome_resource resource_ptr; void foo() {if(!resource_ptr){resource_ptr.reset(new some_resource); //❶}resource_ptr-do_something(); }如果共享资源本身对于并发访问是安全的当将其转换为多线程代码时唯一需要保护的部分就是初始化❶但是像清单3.11中这样的朴素的转换会引起使用该资源的线程产生不必要的序列化。这是因为每个线程都必须等待互斥元以检查资源是否已经被初始化。 //清单3.11 使用互斥元进行线程安全的延迟初始化 #include memory #include mutexstruct some_resource {void do_something(){}};std::shared_ptrsome_resource resource_ptr; std::mutex resource_mutex; void foo() {std::unique_lockstd::mutex lk(resource_mutex); //所有的线程在这里被序列化if(!resource_ptr){resource_ptr.reset(new some_resource); //只有初始化需要被保护}lk.unlock();resource_ptr-do_something(); }int main() {foo(); } 这段代码是很常见的不必要的序列化问题已足够大以至于许多人都试图想出一个更好的方法来实现包括臭名昭著的二次检查锁定(Double-Checked Locking)模式在不获取锁❶(在下面的代码中的情况下首次读取指针并仅当此指针为NULL时获得该锁。一旦已经获取了锁该指针要被再次检查❷(这就是二次检查的部分)以防止在首次检查和这个线程获取锁之间另一个线程就已经完成了初始化。 void undefined_behaviour_with_double_checked_locking() {if(!resource_ptr) //❶{ std::lock_guardstd::mutex lk(resource_mutex);if(!resource_ptr) //❷{resource_ptr.reset(new some_resource); //❸}}resource_ptr-do_something(); //❹ }不幸的是这种模式因某个原因而臭名昭著。它有可能产生恶劣的竞争条件因为在锁外部的读取❶与锁内部由另一线程完成的写入不同步❸。这就因此创建了一个竞争条件不仅涵盖了指针本身还涵盖了指向的对象。就算一个线程看到另一个线程写入的指针它也可能无法看到新创建的 some_resource 实例从而导致do_something()❹的调用在不正确的值上运行。这是一个竞争条件的例子该类型的竞争条件被C标准定义为数据竞争(data race)因此被定为未定义行为。因此这是肯定需要避免的。 C标准委员会也发现这是一个重要的场景所以C标准库提供了std::once_flag和 std::call_once 来处理这种情况。
阅读全文