Scott Meyers - Effective Modern C++

Здесь есть возможность читать онлайн «Scott Meyers - Effective Modern C++» весь текст электронной книги совершенно бесплатно (целиком полную версию без сокращений). В некоторых случаях можно слушать аудио, скачать через торрент в формате fb2 и присутствует краткое содержание. Город: Sebastopol, Год выпуска: 2014, ISBN: 2014, Издательство: O’Reilly, Жанр: Программирование, на английском языке. Описание произведения, (предисловие) а так же отзывы посетителей доступны на портале библиотеки ЛибКат.

Effective Modern C++: краткое содержание, описание и аннотация

Предлагаем к чтению аннотацию, описание, краткое содержание или предисловие (зависит от того, что написал сам автор книги «Effective Modern C++»). Если вы не нашли необходимую информацию о книге — напишите в комментариях, мы постараемся отыскать её.

Coming to grips with C++11 and C++14 is more than a matter of familiarizing yourself with the features they introduce (e.g., auto type declarations, move semantics, lambda expressions, and concurrency support). The challenge is learning to use those features
— so that your software is correct, efficient, maintainable, and portable. That's where this practical book comes in. It describes how to write truly great software using C++11 and C++14 — i.e., using
C++.
Topics include:
■ The pros and cons of braced initialization,
specifications, perfect forwarding, and smart pointer make functions
■ The relationships among
,
, rvalue references, and universal references
■ Techniques for writing clear, correct,
lambda expressions
■ How
differs from
, how each should be used, and how they relate to C++'s concurrency API
■ How best practices in “old” C++ programming (i.e., C++98) require revision for software development in modern C++
Effective Modern C++ For more than 20 years,
'
books (
,
, and
) have set the bar for C++ programming guidance. His clear, engaging explanations of complex technical material have earned him a worldwide following, keeping him in demand as a trainer, consultant, and conference presenter. He has a Ph.D. in Computer Science from Brown University.
“After I learned the C++ basics, I then learned how to use C++ in production code from Meyers' series of Effective C++ books. Effective Modern C++ is the most important how-to book for advice on key guidelines, styles, and idioms to use modern C++ effectively and well. Don't own it yet? Buy this one. Now.”
Herb Sutter
Chair of ISO C++ Standards Committee and C++ Software Architect at Microsoft

Effective Modern C++ — читать онлайн бесплатно полную книгу (весь текст) целиком

Ниже представлен текст книги, разбитый по страницам. Система сохранения места последней прочитанной страницы, позволяет с удобством читать онлайн бесплатно книгу «Effective Modern C++», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

This kind of bug is easy to overlook during development and unit testing, because it may manifest itself only under heavy loads. Those are the conditions that push the machine towards oversubscription or thread exhaustion, and that's when a task may be most likely to be deferred. After all, if the hardware isn't threatened by oversubscription or thread exhaustion, there's no reason for the runtime system not to schedule the task for concurrent execution.

The fix is simple: just check the future corresponding to the std::asynccall to see whether the task is deferred, and, if so, avoid entering the timeout-based loop. Unfortunately, there's no direct way to ask a future whether its task is deferred. Instead, you have to call a timeout-based function — a function such as wait_for. In this case, you don't really want to wait for anything, you just want to see if the return value is std::future_status::deferred, so stifle your mild disbelief at the necessary circumlocution and call wait_forwith a zero timeout:

auto fut = std::async(f); // as above

if (fut.wait_for(0s) == // if task is

std::future_status::deferred) // deferred...

{

// ...use wait or get on fut

… // to call f synchronously

} else {// task isn't deferred

while (fut.wait_for(100ms) != // infinite loop not

std::future_status::ready) { // possible (assuming

// f finishes)

… // task is neither deferred nor ready,

// so do concurrent work until it's ready

}

… // fut is ready

}

The upshot of these various considerations is that using std::asyncwith the default launch policy for a task is fine as long as the following conditions are fulfilled:

• The task need not run concurrently with the thread calling getor wait.

• It doesn't matter which thread's thread_localvariables are read or written.

• Either there's a guarantee that getor waitwill be called on the future returned by std::asyncor it's acceptable that the task may never execute.

• Code using wait_foror wait_untiltakes the possibility of deferred status into account.

If any of these conditions fails to hold, you probably want to guarantee that std::asyncwill schedule the task for truly asynchronous execution. The way to do that is to pass std::launch::asyncas the first argument when you make the call:

auto fut = std::async( std::launch::async, f); // launch f

// asynchronously

In fact, having a function that acts like std::async, but that automatically uses std::launch::asyncas the launch policy, is a convenient tool to have around, so it's nice that it's easy to write. Here's the C++11 version:

template

inline

std::future::type>

reallyAsync(F&& f, Ts&&... params) // return future

{ // for asynchronous

return std::async( std::launch::async, // call to f(params...)

std::forward(f),

std::forward(params)...);

}

This function receives a callable object fand zero or more parameters paramsand perfect-forwards them (see Item 25) to std::async, passing std::launch::asyncas the launch policy. Like std::async, it returns a std::futurefor the result of invoking fon params. Determining the type of that result is easy, because the type trait std::result_ofgives it to you. (See Item 9for general information on type traits.)

reallyAsyncis used just like std::async:

auto fut = reallyAsync(f); // run f asynchronously;

// throw if std::async

// would throw

In C++14, the ability to deduce reallyAsync's return type streamlines the function declaration:

template

inline

auto // C++14

reallyAsync(F&& f, Ts&&... params) {

return std::async(std::launch::async,

std::forward(f),

std::forward(params)...);

}

This version makes it crystal clear that reallyAsyncdoes nothing but invoke std::asyncwith the std::launch::asynclaunch policy.

Things to Remember

• The default launch policy for std::asyncpermits both asynchronous and synchronous task execution.

• This flexibility leads to uncertainty when accessing thread_locals, implies that the task may never execute, and affects program logic for timeout-based wait calls.

• Specify std::launch::asyncif asynchronous task execution is essential.

Item 37: Make std::threads unjoinable on all paths.

Every std::threadobject is in one of two states: joinable or unjoinable . A joinable std::threadcorresponds to an underlying asynchronous thread of execution that is or could be running. A std::threadcorresponding to an underlying thread that's blocked or waiting to be scheduled is joinable, for example. std::threadobjects corresponding to underlying threads that have run to completion are also considered joinable.

An unjoinable std::threadis what you'd expect: a std:: threadthat's not joinable. Unjoinable std::threadobjects include:

Default-constructed std::thread s. Such std::threads have no function to execute, hence don't correspond to an underlying thread of execution.

std::thread objects that have been moved from. The result of a move is that the underlying thread of execution a std::threadused to correspond to (if any) now corresponds to a different std::thread.

std::thread s that have been join ed. After a join, the std::threadobject no longer corresponds to the underlying thread of execution that has finished running.

std::thread s that have been detach ed. A detachsevers the connection between a std::threadobject and the underlying thread of execution it corresponds to.

One reason a std::thread's joinability is important is that if the destructor for a joinable thread is invoked, execution of the program is terminated. For example, suppose we have a function doWorkthat takes a filtering function, filter, and a maximum value, maxVal, as parameters. doWorkchecks to make sure that all conditions necessary for its computation are satisfied, then performs the computation with all the values between 0 and maxValthat pass the filter. If it's time-consuming to do the filtering and it's also time-consuming to determine whether doWork's conditions are satisfied, it would be reasonable to do those two things concurrently.

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

Похожие книги на «Effective Modern C++»

Представляем Вашему вниманию похожие книги на «Effective Modern C++» списком для выбора. Мы отобрали схожую по названию и смыслу литературу в надежде предоставить читателям больше вариантов отыскать новые, интересные, ещё непрочитанные произведения.


Отзывы о книге «Effective Modern C++»

Обсуждение, отзывы о книге «Effective Modern C++» и просто собственные мнения читателей. Оставьте ваши комментарии, напишите, что Вы думаете о произведении, его смысле или главных героях. Укажите что конкретно понравилось, а что нет, и почему Вы так считаете.

x