forked from Light-City/CPlusPlusThings
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3a495d7
commit 8edbbbc
Showing
179 changed files
with
428 additions
and
26 deletions.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
com.sh |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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.
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.
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.
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// | ||
// Created by light on 19-11-5. | ||
// | ||
|
||
#include <iostream> | ||
#include <thread> | ||
#include <unistd.h> | ||
|
||
using namespace std; | ||
|
||
void hello() { | ||
cout << "hello world" << endl; | ||
} | ||
|
||
int main() { | ||
thread t(hello); | ||
t.join(); // must add this line otherwise will failed! | ||
// 需要注意的是线程对象执行了join后就不再joinable了,所以只能调用join一次。 | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
// | ||
// Created by light on 19-11-5. | ||
// | ||
|
||
#include <iostream> | ||
#include <thread> | ||
#include <unistd.h> | ||
#include <cassert> | ||
|
||
using namespace std; | ||
|
||
class background_task { | ||
public: | ||
void operator()() const { | ||
cout << "ok" << endl; | ||
} | ||
}; | ||
|
||
void do_something(int &i) { | ||
cout << "do_something" << endl; | ||
} | ||
|
||
struct func { | ||
int &i; | ||
|
||
func(int &i_) : i(i_) {} | ||
|
||
void operator()() { | ||
for (unsigned j = 0; j < 1000000; ++j) { | ||
do_something(i); // 1. 潜在访问隐患:悬空引用 | ||
} | ||
} | ||
}; | ||
|
||
// 特殊情况下的等待 | ||
void f() { | ||
int some_local_state = 0; | ||
func my_func(some_local_state); | ||
std::thread t(my_func); | ||
try { | ||
// do_something_in_current_thread(); | ||
} | ||
catch (...) { | ||
t.join(); // 1 | ||
throw; | ||
} | ||
t.join(); // 2 | ||
} | ||
|
||
// try catch 只能捕获轻量级错误,所以如需确保线程在函数之前结束——查看是否因为线程函数使用了局部变量的引用, | ||
// 以及其他原因——而后再确定一下程序可能会退出的途径,无论正常与否,可以提供一个简洁的机制,来做解决这个问题。 | ||
|
||
// 一种方式是使用“资源获取即初始化方式”(RAII,Resource Acquisition Is Initialization),并且提供一个类,在析构函数中使用join(), | ||
// std::thread支持移动的好处是可以创建thread_guard类的实例,并且拥有其线程的所有权。 | ||
class thread_guard { | ||
std::thread &t; | ||
public: | ||
explicit thread_guard(std::thread &t_) : | ||
t(t_) {} | ||
|
||
~thread_guard() { | ||
if (t.joinable()) // 1 | ||
{ | ||
t.join(); // 2 | ||
} | ||
} | ||
|
||
thread_guard(thread_guard const &) = delete; // 3 | ||
thread_guard &operator=(thread_guard const &) = delete; | ||
}; | ||
void f1() | ||
{ | ||
int some_local_state=0; | ||
func my_func(some_local_state); | ||
std::thread t(my_func); | ||
thread_guard g(t); | ||
// do_something_in_current_thread(); | ||
} // 4 | ||
// 当线程执行到4处时,局部对象就要被逆序销毁了。因此,thread_guard对象g是第一个被销毁的, | ||
// 这时线程在析构函数中被加入2到原始线程中。 | ||
// 即使do_something_in_current_thread抛出一个异常,这个销毁依旧会发生。 | ||
|
||
|
||
int main() { | ||
|
||
background_task f; | ||
// thread t(f); // ok | ||
// t.join(); | ||
//声明一个名为my_threadx的函数,这个函数带有一个参数(函数指针指向没有参数并返回background_task对象的函数),返回一个std::thread对象的函数 | ||
// thread my_thread1(background_task()); | ||
|
||
// 针对Most Vexing Parse问题解决如下: | ||
// thread my_thread1((background_task())); // 多组括号 | ||
// my_thread1.join(); | ||
// thread my_thread2{background_task()}; // 新的初始化语法 | ||
// my_thread2.join(); | ||
|
||
// thread myThread([](){ | ||
// cout<<"ok"<<endl; | ||
// }); | ||
// myThread.join(); | ||
// 后台运行线程 | ||
std::thread t(f); | ||
t.detach(); | ||
assert(!t.joinable()); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// | ||
// Created by light on 19-11-5. | ||
// | ||
#include <iostream> | ||
#include <thread> | ||
|
||
using namespace std; | ||
|
||
class X { | ||
public: | ||
void do_length_work() {}; | ||
}; | ||
|
||
void process_big_object(std::unique_ptr<X>); | ||
|
||
int main() { | ||
X my_x; | ||
thread t(&X::do_length_work, &my_x); // 1 | ||
|
||
|
||
std::unique_ptr<X> p(new X); | ||
p->do_length_work(); | ||
std::thread tt(process_big_object,std::move(p)); | ||
//std::thread实例的可移动且不可复制性。不可复制保性证了在同一时间点, | ||
// 一个std::thread实例只能关联一个执行线程;可移动性使得程序员可以自己决定,哪个实例拥有实际执行线程的所有权。 | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// | ||
// Created by light on 19-11-5. | ||
// | ||
#include <iostream> | ||
#include <thread> | ||
#include <unistd.h> | ||
#include <vector> | ||
#include <algorithm> | ||
|
||
using namespace std; | ||
|
||
void some_function() {} | ||
|
||
void some_other_function() {} | ||
|
||
// std::thread不支持拷贝语义。 | ||
// std::thread支持移动语义。 | ||
|
||
|
||
|
||
// scoped_thread实例 | ||
void do_something(int i) { | ||
cout << i << endl; | ||
} | ||
|
||
struct func { | ||
int &i; | ||
|
||
func(int &i_) : i(i_) {} | ||
|
||
void operator()() { | ||
for (unsigned j = 0; j < 1000000; ++j) { | ||
do_something(i); | ||
} | ||
} | ||
}; | ||
|
||
class scoped_thread { | ||
std::thread t; | ||
public: | ||
explicit scoped_thread(std::thread t_) : // 1 | ||
t(std::move(t_)) { | ||
if (!t.joinable()) // 2 | ||
throw std::logic_error("No thread"); | ||
} | ||
|
||
~scoped_thread() { | ||
t.join(); // 3 | ||
} | ||
|
||
scoped_thread(scoped_thread const &) = delete; | ||
|
||
scoped_thread &operator=(scoped_thread const &) = delete; | ||
}; | ||
|
||
void do_work(unsigned id) {} | ||
|
||
void f() { | ||
std::vector<std::thread> threads; | ||
for (unsigned i = 0; i < 20; ++i) { | ||
threads.push_back(std::thread(do_work, i)); // 产生线程 | ||
} | ||
std::for_each(threads.begin(), threads.end(), | ||
std::mem_fn(&std::thread::join)); // 对每个线程调用join() | ||
} | ||
|
||
int main() { | ||
// std::thread t1(some_function); // 构造一个thread对象t1 | ||
// std::thread t2 = std::move(t1); // 把t1 move给另外一个thread对象t2,t1不再管理之前的线程了。 | ||
// // 这句不需要std::move(),从临时变量进行移动是自动和隐式的。调用的是operator=(std::thread&&) | ||
// t1 = std::thread(some_other_function); | ||
// std::thread t3; | ||
// t3 = std::move(t2); // 把t2 move给t3 | ||
// // 把t3 move给t1,非法。因为`t1`已经有了一个相关的线程,会调用`std::terminate()`来终止程序。 | ||
// t1 = std::move(t3); | ||
f(); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// | ||
// Created by light on 19-11-5. | ||
// | ||
#include <iostream> | ||
#include <algorithm> | ||
#include <thread> | ||
#include <vector> | ||
#include <numeric> | ||
|
||
using namespace std; | ||
|
||
//使得每个线程具有最小数目的元素以避免过多的线程开销 | ||
template<typename Iterator, typename T> | ||
struct accumulate_block { | ||
void operator()(Iterator first, Iterator last, T &result) { | ||
result = std::accumulate(first, last, result); | ||
} | ||
}; | ||
|
||
template<typename Iterator, typename T> | ||
T parallel_accumlate(Iterator first, Iterator last, T init) { | ||
unsigned long const length = std::distance(first, last); | ||
|
||
if (!length) | ||
return init; | ||
|
||
unsigned long const min_per_thread = 25; | ||
unsigned long const max_threads = (length + min_per_thread - 1) / min_per_thread; | ||
cout<<max_threads<<endl; | ||
unsigned long const hardware_threads = std::thread::hardware_concurrency(); | ||
cout<<hardware_threads<<endl; | ||
unsigned long const num_threads = std::min(hardware_threads != 0 ? hardware_threads : 2, max_threads); | ||
cout<<num_threads<<endl; | ||
unsigned long const block_size = length / num_threads; | ||
cout<<block_size<<endl; | ||
|
||
std::vector<T> results(num_threads); | ||
std::vector<std::thread> threads(num_threads - 1); | ||
|
||
Iterator block_start = first; | ||
for (unsigned long i = 0; i < (num_threads - 1); ++i) { | ||
Iterator block_end = block_start; | ||
std::advance(block_end, block_size); | ||
threads[i] = std::thread(accumulate_block<Iterator, T>(), block_start, block_end, std::ref(results[i])); | ||
block_start = block_end; | ||
} | ||
accumulate_block<Iterator, T>()(block_start, last, results[num_threads - 1]); | ||
std::for_each(threads.begin(), threads.end(), std::mem_fn(&std::thread::join)); | ||
|
||
return std::accumulate(results.begin(), results.end(), init); | ||
} | ||
|
||
|
||
int main() { | ||
|
||
vector<int> v{3,4,5,6}; | ||
int res=0; | ||
cout<<parallel_accumlate(v.begin(),v.end(),res); | ||
return 0; | ||
} |
Oops, something went wrong.