当前位置: 首页 > wzjs >正文

php做的网站怎么运行物联网平台层的主要功能

php做的网站怎么运行,物联网平台层的主要功能,西安seo服务外包,制作网站用什么软件协程 c20的协程三大标签:“性能之优秀”,“开发之灵活”,“门槛之高” 在讲解c的协程使用前,我们需要先明白协程是什么,协程可以理解为用户态的线程,它需要由程序来进行调度,如上下文切换与调…

协程

c++20的协程三大标签:“性能之优秀”,“开发之灵活”,“门槛之高”

在讲解c++的协程使用前,我们需要先明白协程是什么,协程可以理解为用户态的线程,它需要由程序来进行调度,如上下文切换与调度设计都需要程序来设计,并且协程运行在单个线程中,这就成就了协程的低成本,更直接一点的解释可以说,协程就是一种可以被挂起与恢复的特殊函数。
协程并不会真正地“脱离”当前的线程,它只是让控制流从一个函数流转到另一个地方,然后再回来。这个过程是 轻量级非阻塞 的。
协程可以分为两种类型对称型与非对称型协程:

  • 非对称协程:控制权的转移是单向的,总是从调用者协程转移到被调用者协程,并且被调用者协程必须将控制权返回给调用者协程。
  • 对称协程:控制权可以在任意两个协程之间直接转移。协程在执行过程中可以选择将控制权交给其他任何协程,而不依赖于特定的调用层次关系。

c++协程的基本概念

c++提供的协程是典型的非对称协程,c++中的协程有两个特定条件:

  1. 协程函数必须包含至少一个协程关键字(co_awaitco_yieldco_return
    • co_await: 主要用于暂停协程的执行,同时等待某个异步操作完成。在协程执行到 co_await 表达式时,它会将控制权交还给调用者,待异步操作完成后,协程再恢复执行。
    • co_yield: 主要用于生成器模式,它会产生一个值,然后暂停协程的执行。每次调用生成器的迭代器时,协程会恢复执行,直到下一个 co_yield 或者协程结束。
    • co_return: 用于结束协程的执行,并返回一个值(如果协程有返回类型)。当协程执行到 co_return 时,它会销毁自身的栈帧,并将控制权交还给调用者。
      这里先简单介绍协程的基本概念和使用,后面会结合更多代码解释每一个点
  2. 返回值必须是实现了promise_type结构体的一个类或者结构体;
struct Task {struct promise_type {Task get_return_object() { return {}; }std::suspend_never initial_suspend() { return {}; }std::suspend_never final_suspend() noexcept { return {}; }void return_void() {}void unhandled_exception() {}};
};Task task() {std::cout << "Starting coroutine operation..." << std::endl;co_await std::suspend_always{};std::cout << "Coroutine operation completed." << std::endl;
}int main() {task();std::cout << "Main function continues..." << std::endl;return 0;
}// 输出
Starting coroutine operation...
Main function continues...

这个代码简单演示了协程的使用,我们可以看到输出只有两条,并没有输出Coroutine operation completed.,这个程序的运行流程是main函数调用task后,先保存当前上下文,再将当前线程的上下文切换成task的,接下来输出一条内容运行到co_await时,再次保存当前上下文,不过这次会将上下文切换回协程的调用者也就是main,我们后续没有再回到task运行最后一条命令,这里也就没有相关输出了
协程函数的返回类型有特殊要求。返回类型主要用于表示协程的句柄或包装器,它提供了一种方式来管理协程的生命周期,以及与协程进行交互。promise_type主要用来定义协程的生命周期和行为。

  • promise_type必须实现以下关键方法:
    • get_return_object():该函数在协程开始执行之前被调用,其作用是返回协程的返回对象
    • initial_suspend():在协程开始执行时调用,用于决定协程是否在开始时就暂停。std::suspend_never 表示协程不会在开始时暂停,会立即执行。
    • final_suspend():在协程结束执行时调用,用于决定协程是否在结束时暂停。std::suspend_never 表示协程不会在结束时暂停,会立即销毁。
    • unhandled_exception():处理未捕获的异常。
      下面的方法可选
  • return_void() 当调用co_return时会触发这个函数,它触发于final_suspend()之前
  • yield_value() 主要用于生成器返回值
    我们再来明确一下调用时刻,get_return_object()是在协程运行前就被调用了,当存放task();这一行时就会调用get_return_object()函数,因为我们这个演示比较简单不会返回如何东西,我们会在下面的演示中详细介绍,initial_suspend()是在协程开始执行时调用,这个时刻是介于get_return_object()与真正开始运行之间的时候,这些函数名必须一模一样

生成器

template<typename T>
struct Generator {struct promise_type {T value_;auto get_return_object() { return Generator{this}; }auto initial_suspend() noexcept { return std::suspend_always{}; }auto final_suspend() noexcept { return std::suspend_always{}; }void unhandled_exception() { std::terminate(); }auto yield_value(T val) {value_ = val;return std::suspend_always{};}};using Handle = std::coroutine_handle<promise_type>;Handle handle_;explicit Generator(promise_type* p) : handle_(Handle::from_promise(*p)) {}~Generator() { if (handle_) handle_.destroy(); }T next() {if (!handle_.done()) handle_.resume();return handle_.promise().value_;}
};// 斐波那契生成器
Generator<int> fibonacci() {int a = 0, b = 1;while (true) {co_yield a;int temp = a;a = b;b = temp + b;}
}int main() {auto fib = fibonacci();for (int i = 0; i < 10; ++i) {std::cout << fib.next() << " "; }
}// 输出 
0 1 1 2 3 5 8 13 21 34

这个代码使用了一种叫做生成器的特殊类,它需要我们自己实现,作用是获得一次协程的返回值,fibonacci中使用co_yield返回了a,之前我们介绍过co_yield它的作用是,产生一个值然后暂停协程的执行
这里的promise_type结构体多了两个东西,yield_value()函数的作用是把传入的值存储到 value_ 中,并且返回 std::suspend_always{},使得协程暂停。当使用co_yield关键字时就相当于调用了这个函数,T value_用于存放我们的返回值
promise_type结构体外的东西,都是我们可以自定义的这里最重要的就是,代码中的std::coroutine_handle<>,它是一个协程句柄表示一个协程实例的句柄,允许开发者手动控制协程的恢复、销毁或访问其内部状态,它通常实现为一个指针,直接指向协程的状态帧 ,C++20 协程机制中的核心工具类,用于直接操作协程的生命周期和执行流程。它提供了一种底层但灵活的方式来管理协程的状态。我们介绍几个常用的函数

  • Handle::from_promise() 这是一个静态成员函数,用于从 promise_type 对象创建一个协程句柄。在协程的 promise_type 中,通常会使用这个函数来获取协程句柄,以便在返回对象中保存。
  • resume() 恢复协程的执行。如果协程当前处于暂停状态,调用这个函数会让协程从暂停点继续执行,直到下一个暂停点或者协程结束。
  • destroy() 销毁协程,释放协程占用的资源。在协程执行完毕或者不再需要时,应该调用这个函数来避免内存泄漏。
  • bool done() 检查协程是否已经完成。如果协程已经执行完毕,返回 true;否则返回 false
  • promise_type& promise() 返回与协程句柄关联的 promise_type 对象的引用。通过这个引用,你可以访问和修改协程的状态和数据。
    next()函数用于返回值并恢复协程的执行,这里我们通过get_return_object()构建并返回我们的生成器

自定义可等待对象

自定义可等待对象需要满足特定的接口要求,主要涉及await_readyawait_suspendawait_resume这三个成员函数。

  • await_ready:用于判断是否可以立即恢复协程的执行。若返回true,协程会马上恢复;若返回false,协程就会被挂起。
  • await_suspend:在协程挂起时调用,这里可以执行异步操作。在示例中,使用一个新线程来模拟异步操作,操作完成后恢复协程。
  • await_resume:在协程恢复执行时调用,返回异步操作的结果。
template <typename T>
struct FutureAwaitable {std::future<T>& future;bool await_ready() const noexcept {return future.wait_for(std::chrono::seconds(0)) == std::future_status::ready;}void await_suspend(std::coroutine_handle<> handle) const {std::thread([this, handle]() mutable {future.wait();handle.resume();}).detach();}T await_resume() {return future.get();}
};template <typename T>
FutureAwaitable<T> co_awaitable(std::future<T>& future) {return {future};
}struct AsyncTask {struct promise_type {std::promise<int> promise;std::future<int> result = promise.get_future();auto get_return_object() { return AsyncTask{this}; }auto initial_suspend() { return std::suspend_never{}; }auto final_suspend() noexcept { return std::suspend_always{}; }void return_value(int val) {promise.set_value(val);}void unhandled_exception() {std::terminate();}};using Handle = std::coroutine_handle<promise_type>;Handle handle_;explicit AsyncTask(promise_type* p) : handle_(Handle::from_promise(*p)) {}~AsyncTask() {if (handle_) {handle_.destroy();}}int get() {return handle_.promise().result.get();}
};AsyncTask simulate_async_io() {auto future = std::async([] {std::this_thread::sleep_for(std::chrono::seconds(1));return 42;});auto result = co_await co_awaitable(future);co_return result;
}int main() {auto task = simulate_async_io();std::cout << "Waiting..." << std::endl;std::cout << "Result: " << task.get() << std::endl; // 输出: 42return 0;
}

这个代码演示了co_await结合自定义等待对象,实现的异步调用,当我们触发co_await时会等待异步操作的完成,并获得返回值,在等待时协程会挂起让出cpu资源
await_suspend()函数中我们在另一个线程中恢复了协程,协程的执行线程由恢复它的线程决定。handle.resume() 是恢复协程执行的关键操作,它会从协程上次挂起的位置接着执行。由于 handle.resume() 是在新创建的 std::thread 线程里被调用的,所以协程恢复后会继续在这个新线程里执行后续代码。
return_value()yield_value()函数类似,它是用来处理co_return关键字的返回值的


文章转载自:

http://Vr9xrLk6.rLhgx.cn
http://alZU47E2.rLhgx.cn
http://HoTevsNg.rLhgx.cn
http://BxVKc9Gw.rLhgx.cn
http://2rVToUVJ.rLhgx.cn
http://ozS8JPsv.rLhgx.cn
http://pZEKbMf0.rLhgx.cn
http://Tswj4nCg.rLhgx.cn
http://DGWOrVTV.rLhgx.cn
http://pUFOdBIK.rLhgx.cn
http://P98TwJWs.rLhgx.cn
http://nLckb5Hv.rLhgx.cn
http://Fq0xn01n.rLhgx.cn
http://8qC9acGU.rLhgx.cn
http://v0FFYXUx.rLhgx.cn
http://L5yz6W8n.rLhgx.cn
http://lcix6yVl.rLhgx.cn
http://FlgjtWKY.rLhgx.cn
http://qvA3PUYW.rLhgx.cn
http://i1USni2P.rLhgx.cn
http://Vf5RdEyu.rLhgx.cn
http://1aTljlgI.rLhgx.cn
http://DBVLbSme.rLhgx.cn
http://dZn2Jh2u.rLhgx.cn
http://G3c2HeEj.rLhgx.cn
http://avnAQL6f.rLhgx.cn
http://OxVo3dr8.rLhgx.cn
http://M1RsEVC5.rLhgx.cn
http://zNvss5n7.rLhgx.cn
http://WSbBnSP2.rLhgx.cn
http://www.dtcms.com/wzjs/682498.html

相关文章:

  • 网站建设 音频插件seo顾问人
  • 宁波网站推广外包服务网站开发目录规范
  • 设计公司网站模板基金网站制作
  • 贵阳网站微信建设公司网站推广交换链接
  • perl网站建设网站建设维护网页设计
  • 自建站怎么做学动漫设计后悔死了
  • 站酷网网址美工做网站尺寸多少
  • php版本不同于wordpress使用宁波seo免费优化软件
  • 营口pc网站开发商城网站制作教程
  • 郑州企业网站价格工程公司的会计做账有哪些科目
  • seo 网站现在最火的社交电商平台
  • 芜湖设计公司排名网站优化预算
  • 找做网站的公司河南郑州建设信息网
  • 微信公众号制作网站怎么打开公众号
  • 邓州建网站做网站上传服务器吗
  • 网站建设仿站企业公司精美ppt模板免费下载完整版
  • 龙岗专业做网站公司嵌入式软件开发公司
  • 呼和浩特网站建设哪家好365建站网
  • 怎么在网上接网站建设旅游商务网站建设
  • 网站建设推广唯心cidun8网站维护的页面
  • 用asp做网站上网帮助淮南网云小镇最新消息
  • 做网站怎么上线公司装修材料会计分录
  • 结合七牛云做视频网站哈尔滨网站建立公司
  • 狗狗和人做网站建网站 京公网安
  • 有做电动车修车的网站吗什么是整合营销并举例说明
  • 网站开发回扣注册公司后每年要交什么费用
  • 学做网站论坛vip账号破解wordpress vue模板
  • 用wordpress建站难吗网站建设怎么分析市场
  • 一个网站有多少页面杭州市下城区建设厅网站
  • 重庆网站网站建设网站开发流程框架