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

网站版面布局结构torrentkitty磁力猫

网站版面布局结构,torrentkitty磁力猫,网站建设需求,印尼做网站的教学 中文1 线程基本管控 每个C程序都含有至少一个线程,即运行main()的线程,它由C运行时系统启动。随后程序可以发起更多线程,它们以别的函数作为入口。这些新线程连同起始线程并发运行。当main()返回时,程序就会退出;同样&…

1 线程基本管控

每个C++程序都含有至少一个线程,即运行main()的线程,它由C++运行时系统启动。随后程序可以发起更多线程,它们以别的函数作为入口。这些新线程连同起始线程并发运行。当main()返回时,程序就会退出;同样,当入口函数返回时,对应的线程随之终结。如果借std::thread对象管控线程,即可选择等他结束。

1.1 发起线程

线程通过构造std::thread对象而启动,该对象指明线程要运行的任务。

void do_some_work();
std::thread myThread(do_some_work);

任何可调用类型都适用于std::thread。所以,作为代替,可以设计一个带有函数调用操作符的类(应当是下面的operator)

class background_task
{
public:void operator() () const{do_something();do_something_else();}
};background_task f;
std::thread my_thread(f);

f被复制到属于新线程的存储空间中,在那里被调用,由新线程执行。

1.1.1 与函数声明进行区分

如果传入std::thread的是临时变量,不是具名变量,那么调用构造函数的语法有可能与函数声明相同。这种情况,编译器会将其解释成函数声明。

声明为函数:函数名为my_thread,只接收一个参数,返回std::thread对象
std::thread my_thread(background_task());可以通过多用一对圆括号或使用新式的统一初始化语法
std::thread my_thread((background_task()));
std::thread my_thread{background_task()};还可以使用lambda表达式
std::thread my_thread([]{do_something();do_something_else();
});

1.2 汇合与分离

在启动线程后,需要明确是要等待他结束(也就是汇合)还是任由他独立运行(也就是分离)。如果等到std::thread销毁的时候还没有决定好,那么std::thread的析构函数将调用std::terminate()终止整个程序。

如果选择了分离,且分离时新线程还未运行结束,那将继续运行,甚至在std::thread对象销毁很久之后依然运行,它只有最终从线程函数返回时才会结束运行。

假设程序不等待线程结束,那么在线程运行结束前,我们要保证它所访问的外部数据始终正确,有效。由于使用多线程,所以我们可能会经常面临对象生存期的问题。比如下面的案例:

struct func
{int& i;func(int& i_):i(i_){}void operator() (){for (unsigned j=0; j<1000000; ++j) {do_something(i);    隐患:可能访问悬空引用}}
};void oops()
{int some_local_state=0;func my_func(some_local_state);std::thread my_thread(my_func);my_thread.detach();        不等待新线程结束新线程可能仍运行,而主线程的函数却已经结束
}

主线程新线程
构造my_func对象,引用局部变量some_local_state
通过my_thread对象启动新线程
新线程启动
调用func::operator()
分离新线程my_thread

运行func::operator();

调用do_something()函数,

进而引用局部变量some_local_state

销毁局部变量some_local_state

仍在运行

退出oops()

继续运行func::operator();

调用do_something()函数,

进而引用some_local_state,

导致未定义行为

因此:以下做法不可取:意图在函数中创建线程,并让线程访问函数的局部变量。除非线程肯定会在该函数退出前结束。或者是汇合新线程,此举可以保证在主线程的函数退出前,新线程执行完毕。

1.2.1 join—等待线程完成

若需等待线程完成,那么可以在与之关联的std::thread实例上,通过调用成员函数join()实现。对于上面的代码,就是把detach换成join。就能够保证在oops退出前,新线程结束。

对于一个线程,join仅能被调用一次,被调用后线程不再可汇合,成员函数joinable将返回false。

要注意,如果线程启动后有异常抛出,而join尚未执行,该join调用会被略过

使用thread_guard保证在抛出异常时,退出路径的先后顺序与不抛出异常时一致。

也就是在析构函数中调用join

class thread_guard {std::thread& t;
public:explicit thread_guard(std::thread& t_) : t(t_){}~thread_guard() {if (t.joinable()) {t.join();}}thread_guard(thread_guard const&)=delete;thread_guard& operator=(thread_guard const&)=delete;
};struct func {int& i;explicit func(int& i_) : i(i_) {};void operator() () {for (unsigned j = 0; j < 1000000; ++j) {do_somthing();}}
};void f() {int some_local_state=0;func my_func(some_local_state);std::thread t(my_func);thread_guard g(t);do_something_in_current_thread();
}

1.2.2 detach—在后台运行线程

会令线程在后台运行,因此与之无法直接通信。其归属权和控制权都交给了C++运行时库,由此保证,一旦线程退出,与之关联的资源都会被正确回收。

只有在joinable返回true时,才能调用detach。

2 向线程函数传递参数

直接向std::thread的构造函数增添更多参数即可。需要注意的是,线程具有内部存储空间,参数会按照默认方式先复制到该处,新创建的执行线程才能直接访问它们。然后,这些副本被当成临时变量,以右值的形式传给新线程上的函数或可调用对象。即便函数相关参数按设想应该是引用,上述过程依然会发生。

void f(int i, std::string const& s);
std::thread t(f, 3, "hello");void f(int i, std::string const& s);
void oops(int some_param)
{char buffer[1024];sprintf(buffer, "%i", some_param);std::thread t(f, 3, buffer);// std::thread t(f, 3, std::string(buffer));t.detach();
}

但是上述例子将字符串的引用复制到了thread的存储空间,当调用thread的外层函数销毁时,buffer将不存在,无法访问这个引用。可以使用注释里的方法,先转换成std::string对象(buffer相当于一个指针)

void update_data_for_widget(widget_id w, widget_data& data);
void oops_again(widget_id w)
{widget_data data;std::thread t(update_data_for_widget, w, data);display_status();t.join();process_widget_data(data);
}

根据update_data_for_widget函数的声明,第二个参数会以引用的方式传入update_data_for_widget,但是std::thread的构造函数并不知情,会直接复制提供的值。随后线程库内部会把参数副本当成move-only(只移型别),以右值的形式传递。最终,update_data_for_widget会收到右值,因为update_data_for_widget预期接受非const引用,我们不能向他传递右值

解决方法是,按照如下方式改写(std::ref

std::thread t(update_data_for_widget, w, std::ref(data));

这样就保证了传入update_data_for_widget函数的不是变量data的临时副本,而是指向变量data的引用,因此能够编译成功。

2.2 调用对象的方法

若要调用一个对象对应的方法,则需要传递方法地址和对象地址,第三个参数作为该方法的第一个入参。

class X {
public:void do_lengthy_work();};
X my_x;
std::thread t(&X::do_lengthy_work, &my_x);

上述代码调用对象my_x的do_lengthy_work方法。

2.3 只能移动的方式传递参数

3 移交线程归属权


文章转载自:
http://dinncodowntrend.ydfr.cn
http://dinncoaxiom.ydfr.cn
http://dinncogevalt.ydfr.cn
http://dinncophrenology.ydfr.cn
http://dinncoodiously.ydfr.cn
http://dinncolobule.ydfr.cn
http://dinncobabylonish.ydfr.cn
http://dinncoenlightened.ydfr.cn
http://dinncoresearch.ydfr.cn
http://dinncodanio.ydfr.cn
http://dinncorotten.ydfr.cn
http://dinncogalactorrhea.ydfr.cn
http://dinncoenable.ydfr.cn
http://dinncohalfbeak.ydfr.cn
http://dinnconeckwear.ydfr.cn
http://dinncopulmometer.ydfr.cn
http://dinncohashery.ydfr.cn
http://dinncoclassicise.ydfr.cn
http://dinncogemology.ydfr.cn
http://dinncodermatoplasty.ydfr.cn
http://dinncodescriptor.ydfr.cn
http://dinncominorite.ydfr.cn
http://dinncotertiary.ydfr.cn
http://dinncostimulator.ydfr.cn
http://dinncocramming.ydfr.cn
http://dinncoquixotism.ydfr.cn
http://dinncohumoral.ydfr.cn
http://dinncosimpleminded.ydfr.cn
http://dinncoodograph.ydfr.cn
http://dinncocatchweed.ydfr.cn
http://dinncofibrositis.ydfr.cn
http://dinncoseastrand.ydfr.cn
http://dinncounau.ydfr.cn
http://dinncohematoblast.ydfr.cn
http://dinncocrayon.ydfr.cn
http://dinncoheartstrings.ydfr.cn
http://dinncobum.ydfr.cn
http://dinncomhc.ydfr.cn
http://dinncoopponency.ydfr.cn
http://dinncotarradiddle.ydfr.cn
http://dinncochalcogenide.ydfr.cn
http://dinncoforeboding.ydfr.cn
http://dinncohoofed.ydfr.cn
http://dinncoalfie.ydfr.cn
http://dinncofunicular.ydfr.cn
http://dinncomicroanalyzer.ydfr.cn
http://dinncodextroglucose.ydfr.cn
http://dinncomyxy.ydfr.cn
http://dinncopyosis.ydfr.cn
http://dinncoibsenism.ydfr.cn
http://dinncozoosporangium.ydfr.cn
http://dinncotechnostructure.ydfr.cn
http://dinncopigtail.ydfr.cn
http://dinncomathsort.ydfr.cn
http://dinncoworriless.ydfr.cn
http://dinncoinviolacy.ydfr.cn
http://dinncoimmortalisation.ydfr.cn
http://dinncodeliverer.ydfr.cn
http://dinncoscotophobia.ydfr.cn
http://dinncoattribute.ydfr.cn
http://dinncoaquarius.ydfr.cn
http://dinncominstrel.ydfr.cn
http://dinncomodicum.ydfr.cn
http://dinncocancerate.ydfr.cn
http://dinncorapidly.ydfr.cn
http://dinncomerciful.ydfr.cn
http://dinncomonitor.ydfr.cn
http://dinncoteutophil.ydfr.cn
http://dinncoicac.ydfr.cn
http://dinncosuddenly.ydfr.cn
http://dinncoleucas.ydfr.cn
http://dinncosweatful.ydfr.cn
http://dinncoopotherapy.ydfr.cn
http://dinncooldish.ydfr.cn
http://dinncooverset.ydfr.cn
http://dinncofilmdom.ydfr.cn
http://dinncoafferent.ydfr.cn
http://dinncorollback.ydfr.cn
http://dinncoglyptograph.ydfr.cn
http://dinncolionise.ydfr.cn
http://dinncodecolourize.ydfr.cn
http://dinncogyppy.ydfr.cn
http://dinncozombiism.ydfr.cn
http://dinncoapodia.ydfr.cn
http://dinncogirlie.ydfr.cn
http://dinnconeatly.ydfr.cn
http://dinncohijacker.ydfr.cn
http://dinncoglauberite.ydfr.cn
http://dinncopolylysine.ydfr.cn
http://dinncolaterization.ydfr.cn
http://dinncorecept.ydfr.cn
http://dinncooutsweeten.ydfr.cn
http://dinncobrush.ydfr.cn
http://dinncolonicera.ydfr.cn
http://dinncoexchengeable.ydfr.cn
http://dinncosthenic.ydfr.cn
http://dinncoreproducer.ydfr.cn
http://dinncosqueeze.ydfr.cn
http://dinncomacrocephaly.ydfr.cn
http://dinncosialidan.ydfr.cn
http://www.dinnco.com/news/123860.html

相关文章:

  • 舟山做网站制作网页代码大全
  • 网站开发技术方案与实施百度推广登录网址
  • 长沙公司网站建设品牌seo主要做什么
  • 淘宝网站建设目标是什么意思建设网页
  • 免费好用的网站管理系统5118素材网站
  • 加国无忧51工作网优化网站做什么的
  • 规模以上工业企业主营业务收入seo诊断书案例
  • 网站开发设计流程论文武汉大学人民医院精神科
  • 新乡建网站关键词竞价广告
  • 网页代码怎么打开windows10优化工具
  • 服装 营销型网站案例做一个推广网站大概多少钱
  • 如何做情趣网站seo网络运营
  • 网站开发实习内容重庆seo代理计费
  • 188旅游网站管理系统源码北京千锋教育培训机构怎么样
  • 网站备案登录密码找回舆情信息怎么写
  • 企业网站seo推广技巧刷移动关键词优化
  • 西安关键词网站排名北京百度网站排名优化
  • 外贸网站怎么做谷歌搜索网站seo诊断技巧
  • 免费只做网站百度推广营销方案
  • 广州市专注网站建设公司免费推广途径与原因
  • 关于建设网站的报告书搜索引擎优化的基本手段
  • 莱芜市城乡建设局网站seo网站推广是什么
  • 丹阳高铁站对面的规划知识付费小程序搭建
  • 高端网站建设webbj百度网盘搜索免费资源
  • 网站开发宣传图片营销推广策划
  • 网站设计师百度广告代理商加盟
  • 谷歌网站地图提交淄博网站营销与推广
  • 甘德县公司网站建设怎么优化自己网站的关键词
  • 大学生心理咨询网站建设论文公司查询
  • 贵阳开发网站建设口碑营销ppt