Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions code/chapter1/hello-world/hello-world.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,26 @@
* Created: 09/14/2013 09:41:12 AM
*
* Author: Fu Haiping (forhappy), haipingf@gmail.com
*
* Company: ICT ( Institute Of Computing Technology, CAS )
*
* ========================================================================
*/

#include <cstdio>
#include <cstdlib>
#include <iostream> // std::cout
#include <thread> // std::thread
#include <cstdlib> // EXIT_SUCCESS
#include <iostream> // cout
#include <thread> // thread

using namespace std;

void thread_task() {
std::cout << "hello thread" << std::endl;
void thread_task()
{
cout << "hello thread" << endl;
}

int main(int argc, const char *argv[])
{
std::thread t(thread_task);
thread t(thread_task);
t.join();

return EXIT_SUCCESS;
Expand Down
82 changes: 48 additions & 34 deletions zh/chapter3-Thread/Introduction-to-Thread.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,31 @@

>参见 N3242=11-0012 草案第 30.3 节 Threads(p1133)。

namespace std {
#define __STDCPP_THREADS__ __cplusplus
class thread;
void swap(thread& x, thread& y);
namespace this_thread {
thread::id get_id();
void yield();

template <class Clock, class Duration>
void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);

template <class Rep, class Period>
void sleep_for(const chrono::duration<Rep, Period>& rel_time);
}
```cpp
namespace std {
#define __STDCPP_THREADS__ __cplusplus
class thread;
void swap(thread& x, thread& y);
namespace this_thread {
thread::id get_id();
void yield();

template <class Clock, class Duration>
void sleep_until(const chrono::time_point<Clock, Duration>& abs_time);

template <class Rep, class Period>
void sleep_for(const chrono::duration<Rep, Period>& rel_time);
}
}
```

`<thread>` 头文件主要声明了 `std::thread` 类,另外在 `std::this_thread` 命名空间中声明了 `get_id`,`yield`,`sleep_until` 以及 `sleep_for` 等辅助函数,本章稍微会详细介绍 `std::thread` 类及相关函数。


### `std::thread` 类摘要 ###

`std::thread` 代表了一个线程对象,C++11 标准声明如下:

`std::thread` 代表了一个线程对象,C++11 标准声明如下:
```cpp
namespace std {
class thread {
public:
Expand Down Expand Up @@ -59,9 +61,10 @@
static unsigned hardware_concurrency() noexcept;
};
}
```

`std::thread` 中主要声明三类函数:(1). 构造函数、拷贝构造函数及析构函数;(2). 成员函数;(3). 静态成员函数。另外, `std::thread::id` 表示线程 ID,同时 C++11 声明如下:

```cpp
namespace std {
class thread::id {
public:
Expand All @@ -84,6 +87,7 @@
template <class T> struct hash;
template <> struct hash<thread::id>;
}
```

## `std::thread` 详解 ##

Expand Down Expand Up @@ -123,7 +127,7 @@ thread(thread&amp;&amp; x) noexcept;
>注意:可被 `joinable` 的 `std::thread` 对象必须在他们销毁之前被主线程 `join` 或者将其设置为 `detached`.

std::thread 各种构造函数例子如下([参考](http://en.cppreference.com/w/cpp/thread/thread/thread)):

```cpp
#include <iostream>
#include <utility>
#include <thread>
Expand Down Expand Up @@ -159,6 +163,7 @@ std::thread 各种构造函数例子如下([参考](http://en.cppreference.com
t4.join();
std::cout << "Final value of n is " << n << '\n';
}
```

#### `std::thread` 赋值操作 ####

Expand All @@ -181,7 +186,7 @@ thread&amp; operator=(const thread&amp;) = delete;
2. 拷贝赋值操作(2),被禁用,因此 `std::thread` 对象不可拷贝赋值。

请看下面的例子:

```cpp
#include <stdio.h>
#include <stdlib.h>

Expand Down Expand Up @@ -211,13 +216,13 @@ thread&amp; operator=(const thread&amp;) = delete;

return EXIT_SUCCESS;
}

```
### 其他成员函数 ###

> 本小节例子来自 [http://en.cppreference.com ](http://en.cppreference.com/w/cpp/thread/thread)

- `get_id`: 获取线程 ID,返回一个类型为 `std::thread::id` 的对象。请看下面例子:

```cpp
#include <iostream>
#include <thread>
#include <chrono>
Expand All @@ -241,9 +246,10 @@ thread&amp; operator=(const thread&amp;) = delete;
t1.join();
t2.join();
}
```

- `joinable`: 检查线程是否可被 join。检查当前的线程对象是否表示了一个活动的执行线程,由默认构造函数创建的线程是不能被 join 的。另外,如果某个线程 已经执行完任务,但是没有被 join 的话,该线程依然会被认为是一个活动的执行线程,因此也是可以被 join 的。

```cpp
#include <iostream>
#include <thread>
#include <chrono>
Expand All @@ -263,9 +269,9 @@ thread&amp; operator=(const thread&amp;) = delete;

t.join();
}

```
- `join`: Join 线程,调用该函数会阻塞当前线程,直到由 `*this` 所标示的线程执行完毕 join 才返回。

```cpp
#include <iostream>
#include <thread>
#include <chrono>
Expand Down Expand Up @@ -296,6 +302,7 @@ thread&amp; operator=(const thread&amp;) = delete;

std::cout << "done!\n";
}
```

- `detach`: Detach 线程。
将当前线程对象所代表的执行实例与该线程对象分离,使得线程的执行可以单独进行。一旦线程执行完毕,它所分配的资源将会被释放。
Expand All @@ -307,7 +314,7 @@ thread&amp; operator=(const thread&amp;) = delete;
3. get_id() == std::thread::id()

另外,如果出错或者 `joinable() == false`,则会抛出 `std::system_error`.

```cpp
#include <iostream>
#include <chrono>
#include <thread>
Expand All @@ -333,9 +340,10 @@ thread&amp; operator=(const thread&amp;) = delete;
threadCaller();
std::this_thread::sleep_for(std::chrono::seconds(5));
}
```

- `swap`: Swap 线程,交换两个线程对象所代表的底层句柄(underlying handles)。

```cpp
#include <iostream>
#include <thread>
#include <chrono>
Expand Down Expand Up @@ -373,6 +381,7 @@ thread&amp; operator=(const thread&amp;) = delete;
t1.join();
t2.join();
}
```

执行结果如下:

Expand All @@ -386,7 +395,7 @@ thread&amp; operator=(const thread&amp;) = delete;
thread 2 id: 2584

- `native_handle`: 返回 native handle(由于 `std::thread` 的实现和操作系统相关,因此该函数返回与 `std::thread` 具体实现相关的线程句柄,例如在符合 Posix 标准的平台下(如 Unix/Linux)是 Pthread 库)。

```cpp
#include <thread>
#include <iostream>
#include <chrono>
Expand Down Expand Up @@ -421,26 +430,28 @@ thread&amp; operator=(const thread&amp;) = delete;
t1.join();
t2.join();
}
```

执行结果如下:

Thread 2 is executing at priority 0
Thread 1 is executing at priority 20

- `hardware_concurrency` [static]: 检测硬件并发特性,返回当前平台的线程实现所支持的线程并发数目,但返回值仅仅只作为系统提示(hint)。

```cpp
#include <iostream>
#include <thread>

int main() {
unsigned int n = std::thread::hardware_concurrency();
std::cout << n << " concurrent threads are supported.\n";
}
```

## `std::this_thread` 命名空间中相关辅助函数介绍 ##

- get_id: 获取线程 ID。

```cpp
#include <iostream>
#include <thread>
#include <chrono>
Expand All @@ -467,9 +478,10 @@ thread&amp; operator=(const thread&amp;) = delete;
t1.join();
t2.join();
}
```

- yield: 当前线程放弃执行,操作系统调度另一线程继续执行。

```cpp
#include <iostream>
#include <chrono>
#include <thread>
Expand All @@ -496,16 +508,17 @@ thread&amp; operator=(const thread&amp;) = delete;
<< std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count()
<< " microseconds\n";
}
```

- sleep_until: 线程休眠至某个指定的时刻(time point),该线程才被重新唤醒。

```cpp
template< class Clock, class Duration >
void sleep_until( const std::chrono::time_point<Clock,Duration>& sleep_time );

```


- sleep_for: 线程休眠某个指定的时间片(time span),该线程才被重新唤醒,不过由于线程调度等原因,实际休眠时间可能比 `sleep_duration` 所表示的时间片更长。

```cpp
template< class Rep, class Period >
void sleep_for( const std::chrono::duration<Rep,Period>& sleep_duration );

Expand All @@ -520,8 +533,9 @@ thread&amp; operator=(const thread&amp;) = delete;
std::this_thread::sleep_for( dura );
std::cout << "Waited 2000 ms\n";
}
```

执行结果如下:

Hello waiter
Waited 2000 ms
Waited 2000 ms