爆款云主机2核4G限时秒杀,88元/年起!
查看详情

活动

天翼云最新优惠活动,涵盖免费试用,产品折扣等,助您降本增效!
热门活动
  • 618智算钜惠季 爆款云主机2核4G限时秒杀,88元/年起!
  • 免费体验DeepSeek,上天翼云息壤 NEW 新老用户均可免费体验2500万Tokens,限时两周
  • 云上钜惠 HOT 爆款云主机全场特惠,更有万元锦鲤券等你来领!
  • 算力套餐 HOT 让算力触手可及
  • 天翼云脑AOne NEW 连接、保护、办公,All-in-One!
  • 中小企业应用上云专场 产品组合下单即享折上9折起,助力企业快速上云
  • 息壤高校钜惠活动 NEW 天翼云息壤杯高校AI大赛,数款产品享受线上订购超值特惠
  • 天翼云电脑专场 HOT 移动办公新选择,爆款4核8G畅享1年3.5折起,快来抢购!
  • 天翼云奖励推广计划 加入成为云推官,推荐新用户注册下单得现金奖励
免费活动
  • 免费试用中心 HOT 多款云产品免费试用,快来开启云上之旅
  • 天翼云用户体验官 NEW 您的洞察,重塑科技边界

智算服务

打造统一的产品能力,实现算网调度、训练推理、技术架构、资源管理一体化智算服务
智算云(DeepSeek专区)
科研助手
  • 算力商城
  • 应用商城
  • 开发机
  • 并行计算
算力互联调度平台
  • 应用市场
  • 算力市场
  • 算力调度推荐
一站式智算服务平台
  • 模型广场
  • 体验中心
  • 服务接入
智算一体机
  • 智算一体机
大模型
  • DeepSeek-R1-昇腾版(671B)
  • DeepSeek-R1-英伟达版(671B)
  • DeepSeek-V3-昇腾版(671B)
  • DeepSeek-R1-Distill-Llama-70B
  • DeepSeek-R1-Distill-Qwen-32B
  • Qwen2-72B-Instruct
  • StableDiffusion-V2.1
  • TeleChat-12B

应用商城

天翼云精选行业优秀合作伙伴及千余款商品,提供一站式云上应用服务
进入甄选商城进入云市场创新解决方案
办公协同
  • WPS云文档
  • 安全邮箱
  • EMM手机管家
  • 智能商业平台
财务管理
  • 工资条
  • 税务风控云
企业应用
  • 翼信息化运维服务
  • 翼视频云归档解决方案
工业能源
  • 智慧工厂_生产流程管理解决方案
  • 智慧工地
建站工具
  • SSL证书
  • 新域名服务
网络工具
  • 翼云加速
灾备迁移
  • 云管家2.0
  • 翼备份
资源管理
  • 全栈混合云敏捷版(软件)
  • 全栈混合云敏捷版(一体机)
行业应用
  • 翼电子教室
  • 翼智慧显示一体化解决方案

合作伙伴

天翼云携手合作伙伴,共创云上生态,合作共赢
天翼云生态合作中心
  • 天翼云生态合作中心
天翼云渠道合作伙伴
  • 天翼云代理渠道合作伙伴
天翼云服务合作伙伴
  • 天翼云集成商交付能力认证
天翼云应用合作伙伴
  • 天翼云云市场合作伙伴
  • 天翼云甄选商城合作伙伴
天翼云技术合作伙伴
  • 天翼云OpenAPI中心
  • 天翼云EasyCoding平台
天翼云培训认证
  • 天翼云学堂
  • 天翼云市场商学院
天翼云合作计划
  • 云汇计划
天翼云东升计划
  • 适配中心
  • 东升计划
  • 适配互认证

开发者

开发者相关功能入口汇聚
技术社区
  • 专栏文章
  • 互动问答
  • 技术视频
资源与工具
  • OpenAPI中心
开放能力
  • EasyCoding敏捷开发平台
培训与认证
  • 天翼云学堂
  • 天翼云认证
魔乐社区
  • 魔乐社区

支持与服务

为您提供全方位支持与服务,全流程技术保障,助您轻松上云,安全无忧
文档与工具
  • 文档中心
  • 新手上云
  • 自助服务
  • OpenAPI中心
定价
  • 价格计算器
  • 定价策略
基础服务
  • 售前咨询
  • 在线支持
  • 在线支持
  • 工单服务
  • 建议与反馈
  • 用户体验官
  • 服务保障
  • 客户公告
  • 会员中心
增值服务
  • 红心服务
  • 首保服务
  • 客户支持计划
  • 专家技术服务
  • 备案管家

了解天翼云

天翼云秉承央企使命,致力于成为数字经济主力军,投身科技强国伟大事业,为用户提供安全、普惠云服务
品牌介绍
  • 关于天翼云
  • 智算云
  • 天翼云4.0
  • 新闻资讯
  • 天翼云APP
基础设施
  • 全球基础设施
  • 信任中心
最佳实践
  • 精选案例
  • 超级探访
  • 云杂志
  • 分析师和白皮书
  • 天翼云·创新直播间
市场活动
  • 2025智能云生态大会
  • 2024智算云生态大会
  • 2023云生态大会
  • 2022云生态大会
  • 天翼云中国行
天翼云
  • 活动
  • 智算服务
  • 产品
  • 解决方案
  • 应用商城
  • 合作伙伴
  • 开发者
  • 支持与服务
  • 了解天翼云
      • 文档
      • 控制中心
      • 备案
      • 管理中心

      【多线程】c++11多线程编程(一)——初识

      首页 知识中心 软件开发 文章详情页

      【多线程】c++11多线程编程(一)——初识

      2025-02-10 08:54:34 阅读次数:10

      join,任务,函数,多线程,并发,执行,线程

      什么是并发

      并发在生活中随处可见,边走路边说话,边听歌边写代码。计算机术语中的"并发",指的是在单个系统里同时执行多个独立的活动,而不是顺序的一个接一个的执行。对于单核CPU来说,在某个时刻只可能处理一个任务,但它却不是完全执行完一个任务再执行一个下一任务,而是一直在任务间切换,每个任务完成一点就去执行下一个任务,看起来就像任务在并行发生,虽然不是严格的同时执行多个任务,但是我们仍然称之为并发(concurrency)。真正的并发是在在多核CPU上,能够真正的同时执行多个任务,称为硬件并发(hardware concurrency)。

      并发并非没有代价,在单核CPU并发执行两个任务需要付出上下文切换的时间代价。如下图:

      【多线程】c++11多线程编程(一)——初识

      双核机器的并行执行与单核机器对比.png

      假设A和B两个任务都被分成10个大小相等的块,单核CPU交替的执行两个任务,每次执行其中一块,其花费的时间并不是先完成A任务再玩成B任务所花费时间的两倍,而是要更多。这是因为系统从一个任务切换到另一个任务需要执行一次上下文切换,这是需要时间的(图中的灰色块)。上下文切换需要操作系统为当前运行的任务保存CPU的状态和指令指针,算出要切换到哪个任务,并为要切换的任务重新加载处理器状态。然后将新任务的指令和数据载入到缓存中。

      并发的方式

      多进程并发

      将应用程序分为多个独立的、单线程的进程,他们可以同时运行。进程内部实现原理比较复杂,这里就不多说了。

      【多线程】c++11多线程编程(一)——初识

      并发运行的进程之间的通信.png

      这些独立的进程可以通过常规的进程间通信机制进行通信,如管道、信号、消息队列、共享内存、存储映射I/O、信号量、套接字等。

      缺点:

      • 进程间通信较为复杂,速度相对线程间的通信更慢。
      • 启动进程的开销比线程大,使用的系统资源也更多。

      优点:

      • 进程间通信的机制相对于线程更加安全。
      • 能够很容易的将一台机器上的多进程程序部署在不同的机器上(如果通信机制选取的是套接字的话)。

      多线程并发

      线程很像轻量级的进程,但是一个进程中的所有线程都共享相同的地址空间,线程间的大部分数据都可以共享。线程间的通信一般都通过共享内存来实现。

      【多线程】c++11多线程编程(一)——初识

      并发运行的线程之间的通信.png

      优点:

      • 由于可以共享数据,多线程间的通信开销比进程小的多。
      • 线程启动的比进程快,占用的资源更少。

      缺点:

      • 共享数据太过于灵活,为了维护正确的共享,代码写起来比较复杂。
      • 无法部署在分布式系统上。

      为什么使用并发

      主要原因有两个:任务拆分和提高性能。

      任务拆分

      在编写软件的时候,将相关的代码放在一起,将无关的代码分开,这是一个好主意,这样能够让程序更加容易理解和测试。将程序划分成不同的任务,每个线程执行一个任务或者多个任务,可以将整个程序的逻辑变得更加简单。

      提高性能

      在两种情况下,并发能够提高性能。

      1. 任务并行(task parallelism):将一个单个任务分成若干个部分各自并行运行,从而降低运行时间。虽然听起来很简单,但其实是一个相当复杂的过程,设想假如各个部分之间存在很多以来,一个部分的执行需要使用到另一个任务的执行结果,这个时候并不能很好的并行完成。
      2. 数据并行(data parallelism):每个线程在不同的数据部分上执行相同的操作。

      多线程库简介

      C++98标准中并没有线程库的存在,而在C++11中终于提供了多线程的标准库,提供了管理线程、保护共享数据、线程间同步操作、原子操作等类。

      多线程库对应的头文件是#include <thread>,类名为std::thread。

      一个简单的串行程序如下:

       

      #include <iostream>
      #include <thread>
      
      void function_1() {
          std::cout << "I'm function_1()" << std::endl;
      }
      
      int main() {
          function_1();
          return 0;
      }
      

      这是一个典型的单线程的单进程程序,任何程序都是一个进程,main()函数就是其中的主线程,单个线程都是顺序执行。

      将上面的程序改造成多线程程序其实很简单,让function_1()函数在另外的线程中执行:

       

      #include <iostream>
      #include <thread>
      
      void function_1() {
          std::cout << "I'm function_1()" << std::endl;
      }
      
      int main() {
          std::thread t1(function_1);
          // do other things
          t1.join();
          return 0;
      }
      

      分析:

      1. 首先,构建一个std::thread对象t1,构造的时候传递了一个参数,这个参数是一个函数,这个函数就是这个线程的入口函数,函数执行完了,整个线程也就执行完了。
      2. 线程创建成功后,就会立即启动,并没有一个类似start的函数来显式的启动线程。
      3. 一旦线程开始运行, 就需要显式的决定是要等待它完成(join),或者分离它让它自行运行(detach)。注意:只需要在std::thread对象被销毁之前做出这个决定。这个例子中,对象t1是栈上变量,在main函数执行结束后就会被销毁,所以需要在main函数结束之前做决定。
      4. 这个例子中选择了使用t1.join(),主线程会一直阻塞着,直到子线程完成,join()函数的另一个任务是回收该线程中使用的资源。

      线程对象和对象内部管理的线程的生命周期并不一样,如果线程执行的快,可能内部的线程已经结束了,但是线程对象还活着,也有可能线程对象已经被析构了,内部的线程还在运行。

      假设t1线程是一个执行的很慢的线程,主线程并不想等待子线程结束就想结束整个任务,直接删掉t1.join()是不行的,程序会被终止(析构t1的时候会调用std::terminate,程序会打印terminate called without an active exception)。

      与之对应,我们可以调用t1.detach(),从而将t1线程放在后台运行,所有权和控制权被转交给C++运行时库,以确保与线程相关联的资源在线程退出后能被正确的回收。参考UNIX的守护进程(daemon process)的概念,这种被分离的线程被称为守护线程(daemon threads)。线程被分离之后,即使该线程对象被析构了,线程还是能够在后台运行,只是由于对象被析构了,主线程不能够通过对象名与这个线程进行通信。例如:

       

      #include <iostream>
      #include <thread>
      
      void function_1() {
          //延时500ms 为了保证test()运行结束之后才打印
          std::this_thread::sleep_for(std::chrono::milliseconds(500)); 
          std::cout << "I'm function_1()" << std::endl;
      }
      
      void test() {
          std::thread t1(function_1);
          t1.detach();
          // t1.join();
          std::cout << "test() finished" << std::endl;
      }
      
      int main() {
          test();
          //让主线程晚于子线程结束
          std::this_thread::sleep_for(std::chrono::milliseconds(1000)); //延时1s
          return 0;
      }
      
      // 使用 t1.detach()时
      // test() finished
      // I'm function_1()
      
      // 使用 t1.join()时
      // I'm function_1()
      // test() finished
      

      分析:

      1. 由于线程入口函数内部有个500ms的延时,所以在还没有打印的时候,test()已经执行完成了,t1已经被析构了,但是它负责的那个线程还是能够运行,这就是detach()的作用。
      2. 如果去掉main函数中的1s延时,会发现什么都没有打印,因为主线程执行的太快,整个程序已经结束了,那个后台线程被C++运行时库回收了。
      3. 如果将t1.detach()换成t1.join(),test函数会在t1线程执行结束之后,才会执行结束。

      一旦一个线程被分离了,就不能够再被join了。如果非要调用,程序就会崩溃,可以使用joinable()函数判断一个线程对象能否调用join()。

       

      void test() {
          std::thread t1(function_1);
          t1.detach();
      
          if(t1.joinable())
              t1.join();
      
          assert(!t1.joinable());
      }
      

      join的必要:

      举个例子,现在有 A, B, C 三件事情,只有做完 A 和 B 才能去做 C,而 A 和 B 可以并行完成。

      int main(){
          thread t = new thread(A);
          B();  // 此时 A 与 B 并行进行
          t.join();  // 确保 A 完成
          C();
      }

      使用 std::thread 创建线程

      C++11 的 std::thread 可以帮助我们方便地写多线程程序,它的使用也是很简单的。

      在 code3 目录下新建一个 code1.cpp 文件:

      #include <iostream>
      #include <functional>
      #include <thread>
      #include <string>
      
      void test(){
          std::cout<<"hello thread"<<std::endl;
      }
      
      struct person{
          void test(){
              std::cout<<"hello thread"<<std::endl;
          }
      
          void test1(std::string str){
              std::cout<<"hello "<<str<<std::endl;
          }
      };
      
      int main() {
          std::thread thd1([]{
              std::cout<<"hello thread"<<std::endl;
          });
      
          std::thread thd2(test);
      
          person p;
          std::thread thd3(std::bind(&person::test, &p));
          std::thread thd4(std::bind(&person::test1, &p, "thread"));
      
          thd1.join();
          thd2.join();
          thd3.join();
          thd4.join();
      
          return 0;
      }
      

       

      编译和运行代码:在 build 目录下执行

      g++ ../code1.cpp -o code1 -lpthread -std=c++11 && ./code1

       

      输出结果如下图所示,可以看到由于每次运行的线程调度可能不一样,多次运行未必结果相同。

      【多线程】c++11多线程编程(一)——初识

      通过 lambda, 普通函数或对象的成员函数就可以创建一个线程了。 这里需要注意的是,构造线程对象并不意味着线程会立即执行,如果不调用 join 方法,那么线程对象就会析构,这时候线程函数执行会出错,所以我们需要调用 join 保证线程函数完整执行,join 是阻塞执行的。如果不希望被阻塞可以采用一些办法,比如调用 detach 或者用一个智能指针来保存 thread 来保证 thread 对象的生命周期。

      在 code3 目录下新建一个 code2.cpp 文件:

      #include <iostream>
      #include <functional>
      #include <thread>
      #include <memory>
      
      char msg1[10] = "hhh";
      char msg2[10] = "aaa";
      char msg3[10] = "ooo";
      
      void test(void *msg)
      {
      
          std::cout << "hello thread " << (char *)msg << std::endl;
      }
      
      struct person
      {
          person() : thd_(std::bind(&person::test, this, (void *)msg2))
          {
              thd_ptr_ = std::make_shared<std::thread>([this]
              {
                  test((void *)msg3);
              });
          }
      
          ~person()
          {
              thd_.join();
              thd_ptr_->join();
          }
      
          void test(void *msg)
          {
              std::cout << "hello thread " << (char *)msg << std::endl;
          }
      
          std::thread thd_;
          std::shared_ptr<std::thread> thd_ptr_;
      };
      
      int main()
      {
      
          std::thread thd(test, (void *)msg1);
          thd.detach();
      
          person p;
      }
      

       

      编译和运行代码:在 build 目录下执行

      g++ ../code2.cpp -o code2 -std=c++11 -lpthread && ./code2

       

      输出结果如下图所示,有时候只输出两个是因为 thd(test) 线程还没有执行,主线程就执行完毕退出了,标准输入输出就不会显示 thd(test) 的输出了。

      【多线程】c++11多线程编程(一)——初识

      接下来,我们来用 thread 做一个定时器,让它定时输出一行字。 在 code3 目录下新建一个 code3.cpp 文件:

      #include <iostream>
      #include <functional>
      #include <thread>
      #include <memory>
      #include <chrono>
      
      struct timer {
          void start() {
              thd_ptr_ = std::make_shared<std::thread>([this]{
                  test();
              });
          }
      
          ~timer(){
              stop_ = true;
              thd_ptr_->join();
          }
      
          void test(){
              while(!stop_){
                  std::cout<<"hello thread"<<std::endl;
                  std::this_thread::sleep_for(std::chrono::seconds(1));
              }
          }
      
          std::shared_ptr<std::thread> thd_ptr_;
          bool stop_ = false;
      };
      
      int main(){
      
          timer t;
          t.start();
      
          std::this_thread::sleep_for(std::chrono::seconds(15));
      }

       

      编译和运行代码:在 build 目录下执行

      g++ ../code3.cpp -o code3 -std=c++11 -lpthread && ./code3

       

      输出结果:

      hello thread
      hello thread
      hello thread
      hello thread
      hello thread
      hello thread
      hello thread
      hello thread
      hello thread
      hello thread
      hello thread
      hello thread
      hello thread
      hello thread
      hello thread

       

      这个定时器会每隔 1s 打印 hello thread 。这里需要注意如何停止一个线程,停止的方法是通过一个停止标志来控制线程函数的结束,换句话说就是让线程自己退出。主函数执行完之后,需要释放 t 因此调用了 t 的析构函数,导致子线程退出。

      线程组的概念与使用

      有时候我们有一批任务,这些任务是可以独立执行的,并且比较耗时,如果按照串行方式在主线程内一个一个执行的话会很耗时,这时候用线程组就可以充分并行地执行任务了,可以大幅缩短任务的执行时间。我们可以通过一个容器去管理 std::thread ,把一批任务分解给每个线程让他们独立并行执行。

      在 code3 目录下新建一个 code4.cpp 文件:

      #include <iostream>
      #include <functional>
      #include <thread>
      #include <memory>
      #include <chrono>
      #include <vector>
      
      void test1(){
          std::cout<<"hello test1"<<std::endl;
          std::this_thread::sleep_for(std::chrono::seconds(1));
      }
      
      void test2(){
          std::cout<<"hello test2"<<std::endl;
          std::this_thread::sleep_for(std::chrono::seconds(2));
      }
      
      void test3(){
          std::cout<<"hello test3"<<std::endl;
          std::this_thread::sleep_for(std::chrono::seconds(3));
      }
      
      int main(){
          auto begin = std::chrono::high_resolution_clock::now();
          test1();
          test2();
          test3();
          auto end = std::chrono::high_resolution_clock::now();
          std::cout<<std::chrono::duration_cast<std::chrono::seconds>(end-begin).count()<<std::endl;
      
          std::vector<std::shared_ptr<std::thread>> group;
          group.push_back(std::make_shared<std::thread>([]{ test1(); }));
          group.push_back(std::make_shared<std::thread>([]{ test2(); }));
          group.push_back(std::make_shared<std::thread>([]{ test3(); }));
      
          begin = std::chrono::high_resolution_clock::now();
          for(auto& thd : group){
              thd->join();
          }
          end = std::chrono::high_resolution_clock::now();
          std::cout<<std::chrono::duration_cast<std::chrono::seconds>(end-begin).count()<<std::endl;
      }

       

      编译和运行代码:在 build 目录下执行

      g++ ../code4.cpp -o code4 -std=c++11 -lpthread && ./code4

      输出结果:

      hello test1
      hello test2
      hello test3
      6 seconds
      hello test1
      hello test2
      hello test3
      3 seconds

      每个线程在创建的时候就开始运行,所以在

      begin = std::chrono::high_resolution_clock::now();

      这个语句执行之前,所有的线程已经开始工作。在主线程 join 等待第一个线程执行完毕的时候,其他的线程仍然在并行工作,所以主线程 join 等待的时间等于子线程的最长工作时间。因此主线程输出为 3 seconds 。

      版权声明:本文内容来自第三方投稿或授权转载,原文地址:https://blog.csdn.net/bandaoyu/article/details/106084199,作者:bandaoyu,版权归原作者所有。本网站转在其作品的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如因作品内容、版权等问题需要同本网站联系,请发邮件至ctyunbbs@chinatelecom.cn沟通。

      上一篇:C++——模版

      下一篇:【内存】C/C++ 自己实现简单的内存泄漏检测工具(重载new/free)

      相关文章

      2025-05-19 09:04:44

      js小题2:构造函数介绍与普通函数对比

      js小题2:构造函数介绍与普通函数对比

      2025-05-19 09:04:44
      new , 关键字 , 函数 , 对象 , 构造函数
      2025-05-19 09:04:38

      mysql只有在任务处于完成状态才能运行

      mysql只有在任务处于完成状态才能运行

      2025-05-19 09:04:38
      MySQL , 任务 , 数据库 , 查询 , 状态
      2025-05-19 09:04:30

      【Canvas技法】辐射式多道光影的实现

      【Canvas技法】辐射式多道光影的实现

      2025-05-19 09:04:30
      代码 , 函数 , 实现
      2025-05-19 09:04:22

      外设驱动库开发笔记54:外设库驱动设计改进的思考

      外设驱动库开发笔记54:外设库驱动设计改进的思考

      2025-05-19 09:04:22
      使用 , 函数 , 初始化 , 定义 , 对象
      2025-05-19 09:04:14

      C语言字符函数和字符串函数--(超全超详细)

      C语言字符函数和字符串函数--(超全超详细)

      2025-05-19 09:04:14
      函数 , 字符 , 字符串
      2025-05-16 09:15:24

      如何将一串数字用函数的方法倒过来(C语言)

      如何将一串数字用函数的方法倒过来(C语言)

      2025-05-16 09:15:24
      函数 , 数字 , 数组
      2025-05-16 09:15:17

      Linux系统基础-多线程超详细讲解(5)_单例模式与线程池

      Linux系统基础-多线程超详细讲解(5)_单例模式与线程池

      2025-05-16 09:15:17
      单例 , 线程 , 队列
      2025-05-14 10:33:31

      计算机小白的成长历程——习题演练(函数篇)

      计算机小白的成长历程——习题演练(函数篇)

      2025-05-14 10:33:31
      函数 , 字符串 , 数组 , 知识点 , 编写 , 迭代 , 递归
      2025-05-14 10:33:31

      【数据结构】第一章——绪论(2)

      【数据结构】第一章——绪论(2)

      2025-05-14 10:33:31
      函数 , 实现 , 打印 , 理解 , 算法 , 输入 , 输出
      2025-05-14 10:33:25

      30天拿下Rust之高级类型

      Rust作为一门系统编程语言,以其独特的内存管理方式和强大的类型系统著称。其中,高级类型的应用,为Rust的开发者提供了丰富的编程工具和手段,使得开发者可以更加灵活和高效地进行编程。

      2025-05-14 10:33:25
      Rust , type , 代码 , 函数 , 类型 , 返回
      查看更多
      推荐标签

      作者介绍

      天翼云小翼
      天翼云用户

      文章

      33561

      阅读量

      5256636

      查看更多

      最新文章

      【Canvas技法】辐射式多道光影的实现

      2025-05-19 09:04:30

      外设驱动库开发笔记54:外设库驱动设计改进的思考

      2025-05-19 09:04:22

      C语言字符函数和字符串函数--(超全超详细)

      2025-05-19 09:04:14

      如何将一串数字用函数的方法倒过来(C语言)

      2025-05-16 09:15:24

      Linux系统基础-多线程超详细讲解(5)_单例模式与线程池

      2025-05-16 09:15:17

      30天拿下Rust之高级类型

      2025-05-14 10:33:25

      查看更多

      热门文章

      Java线程同步synchronized wait notifyAll

      2023-04-18 14:15:05

      JAVA多线程学习笔记

      2023-05-11 06:05:48

      Elasticsearch 处理并发读写操作

      2023-04-24 11:29:46

      Python 函数调用父类详解

      2023-04-23 09:44:31

      Thrift第七课 服务器多线程发送异常

      2023-05-16 09:42:24

      Android Priority Job Queue (Job Manager):线程任务的容错重启机制(二)

      2024-09-25 10:13:46

      查看更多

      热门标签

      java Java python 编程开发 代码 开发语言 算法 线程 Python html 数组 C++ 元素 javascript c++
      查看更多

      相关产品

      弹性云主机

      随时自助获取、弹性伸缩的云服务器资源

      天翼云电脑(公众版)

      便捷、安全、高效的云电脑服务

      对象存储

      高品质、低成本的云上存储服务

      云硬盘

      为云上计算资源提供持久性块存储

      查看更多

      随机文章

      C/C++ 获取线程入口地址模块等

      JavaEE:多线程代码案例(单例模式)

      二级考试C语言基础知识精讲概述(一)

      Python学习笔记-函数与类

      Python----map,filter,reduce,zip,lambda的使用方法

      Python爬虫-第四章-3-多线程多进程提升任务执行效率

      • 7*24小时售后
      • 无忧退款
      • 免费备案
      • 专家服务
      售前咨询热线
      400-810-9889转1
      关注天翼云
      • 旗舰店
      • 天翼云APP
      • 天翼云微信公众号
      服务与支持
      • 备案中心
      • 售前咨询
      • 智能客服
      • 自助服务
      • 工单管理
      • 客户公告
      • 涉诈举报
      账户管理
      • 管理中心
      • 订单管理
      • 余额管理
      • 发票管理
      • 充值汇款
      • 续费管理
      快速入口
      • 天翼云旗舰店
      • 文档中心
      • 最新活动
      • 免费试用
      • 信任中心
      • 天翼云学堂
      云网生态
      • 甄选商城
      • 渠道合作
      • 云市场合作
      了解天翼云
      • 关于天翼云
      • 天翼云APP
      • 服务案例
      • 新闻资讯
      • 联系我们
      热门产品
      • 云电脑
      • 弹性云主机
      • 云电脑政企版
      • 天翼云手机
      • 云数据库
      • 对象存储
      • 云硬盘
      • Web应用防火墙
      • 服务器安全卫士
      • CDN加速
      热门推荐
      • 云服务备份
      • 边缘安全加速平台
      • 全站加速
      • 安全加速
      • 云服务器
      • 云主机
      • 智能边缘云
      • 应用编排服务
      • 微服务引擎
      • 共享流量包
      更多推荐
      • web应用防火墙
      • 密钥管理
      • 等保咨询
      • 安全专区
      • 应用运维管理
      • 云日志服务
      • 文档数据库服务
      • 云搜索服务
      • 数据湖探索
      • 数据仓库服务
      友情链接
      • 中国电信集团
      • 189邮箱
      • 天翼企业云盘
      • 天翼云盘
      ©2025 天翼云科技有限公司版权所有 增值电信业务经营许可证A2.B1.B2-20090001
      公司地址:北京市东城区青龙胡同甲1号、3号2幢2层205-32室
      • 用户协议
      • 隐私政策
      • 个人信息保护
      • 法律声明
      备案 京公网安备11010802043424号 京ICP备 2021034386号