-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add database course lab0 contents (#506)
### What problem were solved in this pull request? Issue Number: close #xxx Problem: ### What is changed and how it works? ### Other information
- Loading branch information
Showing
19 changed files
with
612 additions
and
3 deletions.
There are no files selected for viewing
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
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
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
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
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
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,15 @@ | ||
function(add_custom_executable target_name) | ||
add_executable(${target_name} ${ARGN}) | ||
|
||
set_target_properties(${target_name} PROPERTIES | ||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/cpplings" | ||
) | ||
target_link_libraries(${target_name} PRIVATE pthread) | ||
endfunction() | ||
|
||
add_custom_executable(cas cas.cpp) | ||
add_custom_executable(condition_variable condition_variable.cpp) | ||
add_custom_executable(lambda lambda.cpp) | ||
add_custom_executable(lock lock.cpp) | ||
add_custom_executable(mutex mutex.cpp) | ||
add_custom_executable(smart_pointer smart_pointer.cpp) |
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
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,67 @@ | ||
/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. | ||
miniob is licensed under Mulan PSL v2. | ||
You can use this software according to the terms and conditions of the Mulan PSL v2. | ||
You may obtain a copy of Mulan PSL v2 at: | ||
http://license.coscl.org.cn/MulanPSL2 | ||
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, | ||
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, | ||
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. | ||
See the Mulan PSL v2 for more details. */ | ||
|
||
// CAS (Compare And Swap) 操作通常通过 `std::atomic` 类型的成员函数 `compare_exchange_weak()` | ||
// 或 `compare_exchange_strong()` 函数来实现。 | ||
// `compare_exchange_strong()` 的基本语义是比较一个原子变量的当前值与预期值,如果相等,则将其更新为新值。 | ||
// 如果不相等,则将原子变量的当前值赋值给预期值。这个操作是原子的,保证了线程安全。 | ||
// 详细用法可参考:https://en.cppreference.com/w/cpp/atomic/atomic/compare_exchange | ||
|
||
#include <iostream> // std::cout | ||
#include <thread> // std::thread | ||
#include <vector> // std::vector | ||
#include <cassert> // assert | ||
|
||
// 一个简单的链表节点 | ||
struct Node | ||
{ | ||
int value; | ||
Node *next; | ||
}; | ||
|
||
Node *list_head(nullptr); | ||
|
||
// 向 `list_head` 中添加一个值为 `val` 的 Node 节点。 | ||
void append_node(int val) | ||
{ | ||
Node *old_head = list_head; | ||
Node *new_node = new Node{val, old_head}; | ||
|
||
// TODO: 使用 compare_exchange_strong 来使这段代码线程安全。 | ||
list_head = new_node; | ||
} | ||
|
||
int main() | ||
{ | ||
std::vector<std::thread> threads; | ||
int thread_num = 50; | ||
for (int i = 0; i < thread_num; ++i) | ||
threads.push_back(std::thread(append_node, i)); | ||
for (auto &th : threads) | ||
th.join(); | ||
|
||
// 注意:在 `append_node` 函数是线程安全的情况下,`list_head` 中将包含 50 个 Node 节点。 | ||
int cnt = 0; | ||
for (Node *it = list_head; it != nullptr; it = it->next) { | ||
std::cout << ' ' << it->value; | ||
cnt++; | ||
} | ||
std::cout << '\n'; | ||
assert(cnt == thread_num); | ||
std::cout << cnt << std::endl; | ||
|
||
Node *it; | ||
while ((it = list_head)) { | ||
list_head = it->next; | ||
delete it; | ||
} | ||
std::cout << "passed!" << std::endl; | ||
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,57 @@ | ||
/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. | ||
miniob is licensed under Mulan PSL v2. | ||
You can use this software according to the terms and conditions of the Mulan PSL v2. | ||
You may obtain a copy of Mulan PSL v2 at: | ||
http://license.coscl.org.cn/MulanPSL2 | ||
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, | ||
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, | ||
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. | ||
See the Mulan PSL v2 for more details. */ | ||
|
||
// condition_variable(条件变量)是 C++11 中提供的一种多线程同步机制, | ||
// 它允许一个或多个线程等待另一个线程发出通知,以便能够有效地进行线程同步。 | ||
// wait() 函数用于阻塞线程并等待唤醒,使用 std::unique_lock<std::mutex> 来等待(`void wait(unique_lock<mutex>& Lck);`) | ||
// 如果条件变量当前不满足,线程将被阻塞,同时释放锁,使得其他线程可以继续执行。 | ||
// 当另一个线程调用 notify_one() 或 notify_all() 来通知条件变量时,被阻塞的线程将被唤醒,并再次尝试获取锁。 | ||
// wait() 函数返回时,锁会再次被持有。 | ||
// 详细用法可参考:https://en.cppreference.com/w/cpp/thread/condition_variable | ||
|
||
#include <condition_variable> | ||
#include <iostream> | ||
#include <mutex> | ||
#include <thread> | ||
#include <vector> | ||
#include <cassert> | ||
|
||
int count = 0; | ||
int expect_thread_num = 10; | ||
std::mutex m; | ||
std::condition_variable cv; | ||
|
||
// TODO: 每次调用会增加 count 的值,当count 的值达到 expect 的时候通知 waiter_thread | ||
void add_count_and_notify() | ||
{ | ||
std::scoped_lock slk(m); | ||
count += 1; | ||
} | ||
|
||
void waiter_thread() | ||
{ | ||
// TODO: 等待 count 的值达到 expect_thread_num,然后打印 count 的值 | ||
std::cout << "Printing count: " << count << std::endl; | ||
assert(count == expect_thread_num); | ||
} | ||
|
||
int main() | ||
{ | ||
int thread_num = expect_thread_num; | ||
std::vector<std::thread> threads; | ||
std::thread waiter(waiter_thread); | ||
for (int i = 0; i < thread_num; ++i) | ||
threads.push_back(std::thread(add_count_and_notify)); | ||
waiter.join(); | ||
for (auto &th : threads) | ||
th.join(); | ||
std::cout << "passed!" << std::endl; | ||
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,47 @@ | ||
/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. | ||
miniob is licensed under Mulan PSL v2. | ||
You can use this software according to the terms and conditions of the Mulan PSL v2. | ||
You may obtain a copy of Mulan PSL v2 at: | ||
http://license.coscl.org.cn/MulanPSL2 | ||
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, | ||
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, | ||
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. | ||
See the Mulan PSL v2 for more details. */ | ||
|
||
// lambda 表达式允许我们在另一个函数内定义匿名函数。 | ||
// 嵌套很重要,因为它使我们既可以避免名称空间命名污染, | ||
// 又可以将函数定义为尽可能靠近其使用位置(提供额外的上下文)。 | ||
// Lambda 的形式如下: | ||
// [ captureClause ] ( parameters ) -> returnType | ||
// { | ||
// statements; | ||
// } | ||
// 如果不需要 `capture`,则 `captureClause` 可以为空。 | ||
// 如果不需要 `parameters`,`parameters` 可以为空。除非指定返回类型,否则也可以完全省略它。 | ||
// `returnType` 是可选的,如果省略,则将假定为 auto(使用类型推导来确定返回类型)。 | ||
|
||
#include <iostream> | ||
#include <vector> | ||
#include <cassert> | ||
|
||
int main() | ||
{ | ||
std::vector<int> numbers = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5}; | ||
|
||
// TODO: 定义一个 lambda 表达式来检查数字是否为偶数 | ||
|
||
// 使用 lambda 表达式来累计所有偶数的和 | ||
int even_sum = 0; | ||
for (const auto &num : numbers) { | ||
(void)(num); | ||
// TODO: 在实现 lambda 表达式后将下面的注释取消注释 | ||
// if (is_even(num)) { | ||
// even_sum += num; | ||
// } | ||
} | ||
|
||
std::cout << "Sum of even numbers: " << even_sum << std::endl; | ||
assert(even_sum == 12); | ||
std::cout << "passed!" << std::endl; | ||
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,75 @@ | ||
/* Copyright (c) 2021 OceanBase and/or its affiliates. All rights reserved. | ||
miniob is licensed under Mulan PSL v2. | ||
You can use this software according to the terms and conditions of the Mulan PSL v2. | ||
You may obtain a copy of Mulan PSL v2 at: | ||
http://license.coscl.org.cn/MulanPSL2 | ||
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, | ||
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, | ||
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. | ||
See the Mulan PSL v2 for more details. */ | ||
|
||
/* | ||
lock_guard 是 C++11 中一个简单的 RAII(Resource Acquisition Is Initialization)风格的锁, | ||
用于在作用域内自动管理互斥量的锁定和解锁。当 lock_guard 对象被创建时,它会自动锁定互斥量, | ||
当对象离开作用域时,它会自动解锁互斥量。lock_guard 不支持手动锁定和解锁,也不支持条件变量。 | ||
unique_lock 是 C++11 中一个更灵活的锁,它允许手动锁定和解锁互斥量,以及与 condition_variable 一起使用。 | ||
与 lock_guard 类似,unique_lock 也是一个 RAII 风格的锁,当对象离开作用域时,它会自动解锁互斥量。 | ||
unique_lock 还支持 lock() 和 unlock() 等操作。 | ||
scoped_lock 是 C++17 引入的一个锁,用于同时锁定多个互斥量,以避免死锁。 | ||
scoped_lock 是一个 RAII 风格的锁,当对象离开作用域时,它会自动解锁所有互斥量。 | ||
scoped_lock 不支持手动锁定和解锁,也不支持条件变量。 | ||
它的主要用途是在需要同时锁定多个互斥量时提供简单且安全的解决方案。 | ||
*/ | ||
|
||
#include <iostream> // std::cout | ||
#include <thread> // std::thread | ||
#include <vector> // std::vector | ||
#include <cassert> // assert | ||
|
||
struct Node | ||
{ | ||
int value; | ||
Node *next; | ||
}; | ||
|
||
Node *list_head(nullptr); | ||
|
||
// 向 `list_head` 中添加一个 value 为 `val` 的 Node 节点。 | ||
void append_node(int val) | ||
{ | ||
Node *old_head = list_head; | ||
Node *new_node = new Node{val, old_head}; | ||
|
||
// TODO: 使用 scoped_lock/unique_lock 来使这段代码线程安全。 | ||
list_head = new_node; | ||
} | ||
|
||
int main() | ||
{ | ||
std::vector<std::thread> threads; | ||
int thread_num = 50; | ||
for (int i = 0; i < thread_num; ++i) | ||
threads.push_back(std::thread(append_node, i)); | ||
for (auto &th : threads) | ||
th.join(); | ||
|
||
// 注意:在 `append_node` 函数是线程安全的情况下,`list_head` 中将包含 50 个 Node 节点。 | ||
int cnt = 0; | ||
for (Node *it = list_head; it != nullptr; it = it->next) { | ||
std::cout << ' ' << it->value; | ||
cnt++; | ||
} | ||
std::cout << '\n'; | ||
assert(cnt == thread_num); | ||
std::cout << cnt << std::endl; | ||
|
||
Node *it; | ||
while ((it = list_head)) { | ||
list_head = it->next; | ||
delete it; | ||
} | ||
std::cout << "passed!" << std::endl; | ||
return 0; | ||
} |
Oops, something went wrong.