JavaScript is required to for searching.
跳过导航链接
退出打印视图
Oracle Solaris Studio 12.2:C++ 用户指南
search filter icon
search icon

文档信息

前言

第 1 部分C++ 编译器

1.  C++ 编译器

2.  使用 C++ 编译器

3.  使用 C++ 编译器选项

第 2 部分编写 C++ 程序

4.  语言扩展

5.  程序组织

6.  创建和使用模板

7.  编译模板

8.  异常处理

9.  改善程序性能

10.  生成多线程程序

10.1 生成多线程程序

10.1.1 表明多线程编译

10.1.2 与线程和信号一起使用 C++ 支持库

10.2 在多线程程序中使用异常

10.2.1 线程取消

10.3 在线程之间共享 C++ 标准库对象

10.4 在多线程环境中使用传统 iostream

10.4.1 MT 安全的 iostream 库的组织

10.4.1.1 公共转换例程

10.4.1.2 使用 MT 安全的 libC 库进行编译和链接

10.4.1.3 MT 安全的 iostream 限制

10.4.1.4 减少多线程安全类的性能开销

10.4.2 iostream 库接口更改

10.4.2.1 新增类

10.4.2.2 新增类的分层结构

10.4.2.3 新增函数

10.4.3 全局和静态数据

10.4.4 序列执行

10.4.5 对象锁定

10.4.5.1 stream_locker

10.4.6 多线程安全类

10.4.7 对象析构

10.4.8 示例应用程序

10.5 内存边界内部函数

第 3 部分库

11.  使用库

12.  使用 C++ 标准库

13.  使用传统 iostream

14.  使用复数运算库

15.  生成库

第 4 部分附录

A.  C++ 编译器选项

B.  Pragma

词汇表

索引

10.3 在线程之间共享 C++ 标准库对象

C++ 标准库(libCstd -library=Cstd)是 MT 安全的(有些语言环境下例外),确保了在多线程环境中库内部正常工作。但是,您仍需要将各个线程之间要共享的库对象锁定起来。请参见 setlocale(3C) 和 attributes(5) 手册页。

例如,如果实例化字符串,然后创建新的线程并使用引用将字符串传递给线程。因为要在线程之间显示共享这个字符串对象,所以您必须锁定对于该字符串的写访问。(库提供的用于完成该任务的工具在下文中会有描述。)

另一方面,如果将字符串按值传递给新线程,即使两个不同的线程中的字符串应用 Rogue Wave 的“copy on write(写时复制)”技术共享表示,也不必担心锁定。库将自动处理锁定。只有当要使对象显式可用于多线程或在线程之间传递引用,以及使用全局或静态对象时,您才需要锁定。

下文描述了 C++ 标准库内部使用的锁定(同步)机制,该机制用于确保在多线程下出现正确的行为。

_RWSTDMutex_RWSTDGuard 这两个同步类提供了实现多线程安全的机制。

_RWSTDMutex 类通过下列成员函数提供了与平台无关的锁定机制:

class _RWSTDMutex
{
public:
    _RWSTDMutex ();
    ~_RWSTDMutex ();
    void acquire ();
    void release ();
};

_RWSTDGuard 类是封装有 _RWSTDMutex 类的对象的公用包装器类。_RWSTDGuard 对象尝试在其构造函数中获取封装的互斥锁(抛出从 std::exception on error 派生的 ::thread_error 类型的异常),并在析构函数中释放互斥锁(析构函数从来不会抛出异常)。

class _RWSTDGuard
{
public:
    _RWSTDGuard (_RWSTDMutex&);
    ~_RWSTDGuard ();
};

另外,可以使用宏 _RWSTD_MT_GUARD(mutex)(以前的 _STDGUARD)有条件地在多线程生成中创建 _RWSTDGuard 的对象。该对象保护代码块的其余部分,并在该代码块中定义为可同时被多个线程执行。在单线程生成中,宏扩展到空表达式中。

以下示例说明了这些机制的使用。

#include <rw/stdmutex.h>

//
// An integer shared among multiple threads.
//
int I;

//
// A mutex used to synchronize updates to I.
//
_RWSTDMutex I_mutex;

//
// Increment I by one. Uses an _RWSTDMutex directly.
//

void increment_I ()
{
   I_mutex.acquire(); // Lock the mutex.
   I++;
   I_mutex.release(); // Unlock the mutex.
}

//
// Decrement I by one. Uses an _RWSTDGuard.
//

void decrement_I ()
{
   _RWSTDGuard guard(I_mutex); // Acquire the lock on I_mutex.
   --I;
   //
   // The lock on I is released when destructor is called on guard.
   //
}