Skip to content

Commit a9b3668

Browse files
committed
learning c++11 thread library
1 parent b4eaaef commit a9b3668

12 files changed

Lines changed: 167 additions & 2 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
add_executable (AtomicTest main.cpp)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#include <iostream>
2+
#include <thread>
3+
#include <atomic>
4+
5+
6+
// 将临界资源定义为线程级别的原子操作的数据。
7+
// 即使是多线程,也要像同步进行一样同步操作 atomic 对象,从而省去了 mutex 上锁、解锁的时间消耗。故执行的更快。
8+
std::atomic<int> n = 0;
9+
10+
11+
void count()
12+
{
13+
for (int i = 0; i < 10000; ++i) ++n;
14+
}
15+
16+
17+
int main()
18+
{
19+
std::thread th[100];
20+
21+
for (auto &t : th) t = std::thread(count);
22+
23+
for (auto &t : th) t.join();
24+
25+
std::cout << n << std::endl;
26+
27+
28+
return 0;
29+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
add_subdirectory (AtomicTest)
2+
add_subdirectory (MutexTest)
3+
add_subdirectory (ThreadTest)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
add_executable (MutexTest main.cpp)
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#include <iostream>
2+
#include <thread>
3+
#include <mutex>
4+
5+
6+
int n = 0;
7+
8+
std::mutex mtx;
9+
10+
11+
void count()
12+
{
13+
for (int i = 1; i <= 10000; i++)
14+
{
15+
mtx.lock();
16+
n++;
17+
mtx.unlock();
18+
}
19+
}
20+
21+
22+
int main()
23+
{
24+
std::thread th[100];
25+
26+
for (std::thread &t : th) t = std::thread(count);
27+
28+
for (std::thread &t : th) t.join();
29+
30+
std::cout << n << std::endl; // 加锁以后应该是 10000 * 100 == 1000000
31+
32+
33+
return 0;
34+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# CppThreadLearning
2+
3+
本目录用于学习 C++ 11 多线程的标准库。
4+
5+
参考博客:[https://blog.csdn.net/sjc_0910/article/details/118861539](https://blog.csdn.net/sjc_0910/article/details/118861539)
6+
7+
本目录的构建和其他目录类似,需要在本目录(CppThreadLearning,非含代码的子目录)中添加 .buildme 文件,其余流程相同。
8+
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
add_executable (ThreadTest1 main1.cpp)
2+
add_executable (ThreadTest2 main2.cpp)
3+
add_executable (ThreadTest3 main3.cpp)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#include <iostream>
2+
#include <thread>
3+
4+
5+
void doIt() { std::cout << "Hello, " << std::flush; }
6+
7+
8+
int main()
9+
{
10+
// 线程是在 thread 对象被定义的时候开始执行的。而不是在调用 join() 时才执行的,调用 join() 只是阻塞等待线程结束并回收资源。
11+
std::thread
12+
a(doIt),
13+
b([]()
14+
{ std::cout << "World!" << std::endl; });
15+
16+
// 没有执行 join() 或 detach() 的线程在程序结束时会引发异常。
17+
a.join();
18+
b.join();
19+
20+
21+
return 0;
22+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#include <iostream>
2+
#include <thread>
3+
4+
5+
void countNumber(int id, int n)
6+
{
7+
for (int i = 1; i <= n; ++i)
8+
;
9+
10+
std::cout << "Thread " << id << " finished!" << std::endl;
11+
}
12+
13+
14+
int main()
15+
{
16+
constexpr int threadNum = 10;
17+
18+
std::thread th[threadNum];
19+
20+
for (int i = 0; i < threadNum; i++) th[i] = std::thread(countNumber, i, 100000000);
21+
22+
// thread 库中好像没有类似于 pthread_exit() 退出主线程并且不会影响其余线程的函数,这样就可以无脑 detach() 而不用考虑主线程执行完毕后结束进程的问题了。因此这里还是使用 join() 吧。
23+
for (int i = 0; i < threadNum; i++) th[i].join();
24+
25+
26+
return 0;
27+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#include <iostream>
2+
#include <thread>
3+
4+
5+
template <class T>
6+
void changevalue(T &x, T val) { x = val; }
7+
8+
9+
int main()
10+
{
11+
constexpr int threadNum = 100;
12+
13+
std::thread th[threadNum];
14+
15+
int nums[threadNum];
16+
17+
// 回调函数的参数是一个左值引用,但是 std::thread 需要的是右值引用,因此直接传入编译器会报错
18+
// std::ref 可以包装按引用传递的值;std::cref 可以包装按常量引用传递的值。这样就能把左值引用包装成右值引用
19+
for (int i = 0; i < threadNum; i++) th[i] = std::thread(changevalue<int>, std::ref(nums[i]), i + 1);
20+
21+
for (int i = 0; i < threadNum; i++)
22+
{
23+
th[i].join();
24+
25+
std::cout << nums[i] << ' ';
26+
}
27+
28+
std::cout << std::endl;
29+
30+
31+
return 0;
32+
}

0 commit comments

Comments
 (0)