Skip to content

Commit 8edbbbc

Browse files
committed
update
1 parent 3a495d7 commit 8edbbbc

File tree

179 files changed

+428
-26
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

179 files changed

+428
-26
lines changed

..gitignore.un~

523 Bytes
Binary file not shown.

.com.sh.un~

3.11 KB
Binary file not shown.

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
com.sh

.gitignore~

Whitespace-only changes.

README.md

+50-26

::/:: basic_content/::/::

File renamed without changes.

::/::.cpp basic_content/::/::.cpp

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

inline/iv basic_content/inline/iv

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

struct/sf basic_content/struct/sf

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//
2+
// Created by light on 19-11-5.
3+
//
4+
5+
#include <iostream>
6+
#include <thread>
7+
#include <unistd.h>
8+
9+
using namespace std;
10+
11+
void hello() {
12+
cout << "hello world" << endl;
13+
}
14+
15+
int main() {
16+
thread t(hello);
17+
t.join(); // must add this line otherwise will failed!
18+
// 需要注意的是线程对象执行了join后就不再joinable了,所以只能调用join一次。
19+
return 0;
20+
}

concurrency_v1/chapter2/2.1_basic.cpp

+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
//
2+
// Created by light on 19-11-5.
3+
//
4+
5+
#include <iostream>
6+
#include <thread>
7+
#include <unistd.h>
8+
#include <cassert>
9+
10+
using namespace std;
11+
12+
class background_task {
13+
public:
14+
void operator()() const {
15+
cout << "ok" << endl;
16+
}
17+
};
18+
19+
void do_something(int &i) {
20+
cout << "do_something" << endl;
21+
}
22+
23+
struct func {
24+
int &i;
25+
26+
func(int &i_) : i(i_) {}
27+
28+
void operator()() {
29+
for (unsigned j = 0; j < 1000000; ++j) {
30+
do_something(i); // 1. 潜在访问隐患:悬空引用
31+
}
32+
}
33+
};
34+
35+
// 特殊情况下的等待
36+
void f() {
37+
int some_local_state = 0;
38+
func my_func(some_local_state);
39+
std::thread t(my_func);
40+
try {
41+
// do_something_in_current_thread();
42+
}
43+
catch (...) {
44+
t.join(); // 1
45+
throw;
46+
}
47+
t.join(); // 2
48+
}
49+
50+
// try catch 只能捕获轻量级错误,所以如需确保线程在函数之前结束——查看是否因为线程函数使用了局部变量的引用,
51+
// 以及其他原因——而后再确定一下程序可能会退出的途径,无论正常与否,可以提供一个简洁的机制,来做解决这个问题。
52+
53+
// 一种方式是使用“资源获取即初始化方式”(RAII,Resource Acquisition Is Initialization),并且提供一个类,在析构函数中使用join(),
54+
// std::thread支持移动的好处是可以创建thread_guard类的实例,并且拥有其线程的所有权。
55+
class thread_guard {
56+
std::thread &t;
57+
public:
58+
explicit thread_guard(std::thread &t_) :
59+
t(t_) {}
60+
61+
~thread_guard() {
62+
if (t.joinable()) // 1
63+
{
64+
t.join(); // 2
65+
}
66+
}
67+
68+
thread_guard(thread_guard const &) = delete; // 3
69+
thread_guard &operator=(thread_guard const &) = delete;
70+
};
71+
void f1()
72+
{
73+
int some_local_state=0;
74+
func my_func(some_local_state);
75+
std::thread t(my_func);
76+
thread_guard g(t);
77+
// do_something_in_current_thread();
78+
} // 4
79+
// 当线程执行到4处时,局部对象就要被逆序销毁了。因此,thread_guard对象g是第一个被销毁的,
80+
// 这时线程在析构函数中被加入2到原始线程中。
81+
// 即使do_something_in_current_thread抛出一个异常,这个销毁依旧会发生。
82+
83+
84+
int main() {
85+
86+
background_task f;
87+
// thread t(f); // ok
88+
// t.join();
89+
//声明一个名为my_threadx的函数,这个函数带有一个参数(函数指针指向没有参数并返回background_task对象的函数),返回一个std::thread对象的函数
90+
// thread my_thread1(background_task());
91+
92+
// 针对Most Vexing Parse问题解决如下:
93+
// thread my_thread1((background_task())); // 多组括号
94+
// my_thread1.join();
95+
// thread my_thread2{background_task()}; // 新的初始化语法
96+
// my_thread2.join();
97+
98+
// thread myThread([](){
99+
// cout<<"ok"<<endl;
100+
// });
101+
// myThread.join();
102+
// 后台运行线程
103+
std::thread t(f);
104+
t.detach();
105+
assert(!t.joinable());
106+
107+
return 0;
108+
}
+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//
2+
// Created by light on 19-11-5.
3+
//
4+
#include <iostream>
5+
#include <thread>
6+
7+
using namespace std;
8+
9+
class X {
10+
public:
11+
void do_length_work() {};
12+
};
13+
14+
void process_big_object(std::unique_ptr<X>);
15+
16+
int main() {
17+
X my_x;
18+
thread t(&X::do_length_work, &my_x); // 1
19+
20+
21+
std::unique_ptr<X> p(new X);
22+
p->do_length_work();
23+
std::thread tt(process_big_object,std::move(p));
24+
//std::thread实例的可移动且不可复制性。不可复制保性证了在同一时间点,
25+
// 一个std::thread实例只能关联一个执行线程;可移动性使得程序员可以自己决定,哪个实例拥有实际执行线程的所有权。
26+
return 0;
27+
}
+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
//
2+
// Created by light on 19-11-5.
3+
//
4+
#include <iostream>
5+
#include <thread>
6+
#include <unistd.h>
7+
#include <vector>
8+
#include <algorithm>
9+
10+
using namespace std;
11+
12+
void some_function() {}
13+
14+
void some_other_function() {}
15+
16+
// std::thread不支持拷贝语义。
17+
// std::thread支持移动语义。
18+
19+
20+
21+
// scoped_thread实例
22+
void do_something(int i) {
23+
cout << i << endl;
24+
}
25+
26+
struct func {
27+
int &i;
28+
29+
func(int &i_) : i(i_) {}
30+
31+
void operator()() {
32+
for (unsigned j = 0; j < 1000000; ++j) {
33+
do_something(i);
34+
}
35+
}
36+
};
37+
38+
class scoped_thread {
39+
std::thread t;
40+
public:
41+
explicit scoped_thread(std::thread t_) : // 1
42+
t(std::move(t_)) {
43+
if (!t.joinable()) // 2
44+
throw std::logic_error("No thread");
45+
}
46+
47+
~scoped_thread() {
48+
t.join(); // 3
49+
}
50+
51+
scoped_thread(scoped_thread const &) = delete;
52+
53+
scoped_thread &operator=(scoped_thread const &) = delete;
54+
};
55+
56+
void do_work(unsigned id) {}
57+
58+
void f() {
59+
std::vector<std::thread> threads;
60+
for (unsigned i = 0; i < 20; ++i) {
61+
threads.push_back(std::thread(do_work, i)); // 产生线程
62+
}
63+
std::for_each(threads.begin(), threads.end(),
64+
std::mem_fn(&std::thread::join)); // 对每个线程调用join()
65+
}
66+
67+
int main() {
68+
// std::thread t1(some_function); // 构造一个thread对象t1
69+
// std::thread t2 = std::move(t1); // 把t1 move给另外一个thread对象t2,t1不再管理之前的线程了。
70+
// // 这句不需要std::move(),从临时变量进行移动是自动和隐式的。调用的是operator=(std::thread&&)
71+
// t1 = std::thread(some_other_function);
72+
// std::thread t3;
73+
// t3 = std::move(t2); // 把t2 move给t3
74+
// // 把t3 move给t1,非法。因为`t1`已经有了一个相关的线程,会调用`std::terminate()`来终止程序。
75+
// t1 = std::move(t3);
76+
f();
77+
return 0;
78+
}
+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
//
2+
// Created by light on 19-11-5.
3+
//
4+
#include <iostream>
5+
#include <algorithm>
6+
#include <thread>
7+
#include <vector>
8+
#include <numeric>
9+
10+
using namespace std;
11+
12+
//使得每个线程具有最小数目的元素以避免过多的线程开销
13+
template<typename Iterator, typename T>
14+
struct accumulate_block {
15+
void operator()(Iterator first, Iterator last, T &result) {
16+
result = std::accumulate(first, last, result);
17+
}
18+
};
19+
20+
template<typename Iterator, typename T>
21+
T parallel_accumlate(Iterator first, Iterator last, T init) {
22+
unsigned long const length = std::distance(first, last);
23+
24+
if (!length)
25+
return init;
26+
27+
unsigned long const min_per_thread = 25;
28+
unsigned long const max_threads = (length + min_per_thread - 1) / min_per_thread;
29+
cout<<max_threads<<endl;
30+
unsigned long const hardware_threads = std::thread::hardware_concurrency();
31+
cout<<hardware_threads<<endl;
32+
unsigned long const num_threads = std::min(hardware_threads != 0 ? hardware_threads : 2, max_threads);
33+
cout<<num_threads<<endl;
34+
unsigned long const block_size = length / num_threads;
35+
cout<<block_size<<endl;
36+
37+
std::vector<T> results(num_threads);
38+
std::vector<std::thread> threads(num_threads - 1);
39+
40+
Iterator block_start = first;
41+
for (unsigned long i = 0; i < (num_threads - 1); ++i) {
42+
Iterator block_end = block_start;
43+
std::advance(block_end, block_size);
44+
threads[i] = std::thread(accumulate_block<Iterator, T>(), block_start, block_end, std::ref(results[i]));
45+
block_start = block_end;
46+
}
47+
accumulate_block<Iterator, T>()(block_start, last, results[num_threads - 1]);
48+
std::for_each(threads.begin(), threads.end(), std::mem_fn(&std::thread::join));
49+
50+
return std::accumulate(results.begin(), results.end(), init);
51+
}
52+
53+
54+
int main() {
55+
56+
vector<int> v{3,4,5,6};
57+
int res=0;
58+
cout<<parallel_accumlate(v.begin(),v.end(),res);
59+
return 0;
60+
}

0 commit comments

Comments
 (0)