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++», без необходимости каждый раз заново искать на чём Вы остановились. Поставьте закладку, и сможете в любой момент перейти на страницу, на которой закончили чтение.

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

Интервал:

Закладка:

Сделать

From this perspective, it's interesting that std::threads and futures have such different behaviors in their destructors. As noted in Item 37, destruction of a joinable std::threadterminates your program, because the two obvious alternatives — an implicit joinand an implicit detach— were considered worse choices. Yet the destructor for a future sometimes behaves as if it did an implicit join, sometimes as if it did an implicit detach, and sometimes neither. It never causes program termination. This thread handle behavioral bouillabaisse deserves closer examination.

We'll begin with the observation that a future is one end of a communications channel through which a callee transmits a result to a caller. [18] Item 39 explains that the kind of communications channel associated with a future can be employed for other purposes. For this Item, however, we'll consider only its use as a mechanism for a callee to convey its result to a caller. The callee (usually running asynchronously) writes the result of its computation into the communications channel (typically via a std::promiseobject), and the caller reads that result using a future. You can think of it as follows, where the dashed arrow shows the flow of information from callee to caller:

But where is the callees result stored The callee could finish before the - фото 10

But where is the callee's result stored? The callee could finish before the caller invokes get on a corresponding future, so the result can't be stored in the callee's std::promise. That object, being local to the callee, would be destroyed when the callee finished.

The result can't be stored in the caller's future, either, because (among other reasons) a std::futuremay be used to create a std::shared_future(thus transferring ownership of the callee's result from the std::futureto the std::shared_future), which may then be copied many times after the original std::futureis destroyed. Given that not all result types can be copied (i.e., move-only types) and that the result must live at least as long as the last future referring to it, which of the potentially many futures corresponding to the callee should be the one to contain its result?

Because neither objects associated with the callee nor objects associated with the caller are suitable places to store the callee's result, it's stored in a location outside both. This location is known as the shared state . The shared state is typically represented by a heap-based object, but its type, interface, and implementation are not specified by the Standard. Standard Library authors are free to implement shared states in any way they like.

We can envision the relationship among the callee, the caller, and the shared state as follows, where dashed arrows once again represent the flow of information:

The existence of the shared state is important because the behavior of a - фото 11

The existence of the shared state is important, because the behavior of a future's destructor — the topic of this Item — is determined by the shared state associated with the future. In particular,

The destructor for the last future referring to a shared state for a non-deferred task launched via std::async blocksuntil the task completes. In essence, the destructor for such a future does an implicit join on the thread on which the asynchronously executing task is running.

The destructor for all other futures simply destroys the future object. For asynchronously running tasks, this is akin to an implicit detachon the underlying thread. For deferred tasks for which this is the final future, it means that the deferred task will never run.

These rules sound more complicated than they are. What we're really dealing with is a simple “normal” behavior and one lone exception to it. The normal behavior is that a future's destructor destroys the future object. That's it. It doesn't joinwith anything, it doesn't detachfrom anything, it doesn't run anything. It just destroys the future's data members. (Well, actually, it does one more thing. It decrements the reference count inside the shared state that's manipulated by both the futures referring to it and the callee's std::promise. This reference count makes it possible for the library to know when the shared state can be destroyed. For general information about reference counting, see Item 19.)

The exception to this normal behavior arises only for a future for which all of the following apply:

It refers to a shared state that was created due to a call to std::async .

The task's launch policy is std::launch::async (see Item 36), either because that was chosen by the runtime system or because it was specified in the call to std::async.

The future is the last future referring to the shared state. For std::futures, this will always be the case. For std::shared_futures, if other std::shared_futures refer to the same shared state as the future being destroyed, the future being destroyed follows the normal behavior (i.e., it simply destroys its data members).

Only when all of these conditions are fulfilled does a future's destructor exhibit special behavior, and that behavior is to block until the asynchronously running task completes. Practically speaking, this amounts to an implicit joinwith the thread running the std::async-created task.

It's common to hear this exception to normal future destructor behavior summarized as “Futures from std::asyncblock in their destructors.” To a first approximation, that's correct, but sometimes you need more than a first approximation. Now you know the truth in all its glory and wonder.

Your wonder may take a different form. It may be of the “I wonder why there's a special rule for shared states for non-deferred tasks that are launched by std::async” variety. It's a reasonable question. From what I can tell, the Standardization Committee wanted to avoid the problems associated with an implicit detach(see Item 37), but they didn't want to adopt as radical a policy as mandatory program termination (as they did for joinable std::threads — again, see Item 37), so they compromised on an implicit join. The decision was not without controversy, and there was serious talk about abandoning this behavior for C++14. In the end, no change was made, so the behavior of destructors for futures is consistent in C++11 and C++14.

The API for futures offers no way to determine whether a future refers to a shared state arising from a call to std::async, so given an arbitrary future object, it's not possible to know whether it will block in its destructor waiting for an asynchronously running task to finish. This has some interesting implications:

// this container might block in its dtor, because one or more

// contained futures could refer to a shared state for a non-

// deferred task launched via std::async

std::vector > futs; // see Item 39 for info

// on std::future

class Widget { // Widget objects might

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

Интервал:

Закладка:

Сделать

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

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


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

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

x