#include<thread>
#include<iostream>
#include<string>
using namespace std::chrono_literals;
class MyThread {
public:
void Main() {
std::cout << "MyThread Main" << name << ":" << age;
}
private:
std::string name;
int age = 100;
};
class XThread {
public:
virtual void Start() {
_is_exit = false;
_th = std::thread(&XThread::Main, this);
}
virtual void Stop() {
_is_exit = true;
Wait();
}
virtual void Wait() {
if (_th.joinable())
_th.join();
}
bool is_exit() { return _is_exit; }
private:
virtual void Main() = 0;
std::thread _th;
bool _is_exit = false;
};
class TestXThread:public XThread {
public:
void Main() override {
while (!is_exit()) {
std::this_thread::sleep_for(100ms);
std::cout << "." << std::flush;
}
}
std::string name;
};
超时锁是一种同步机制,用于在尝试获取锁时设置一个超时时间。如果线程在指定的时间内无法获取锁,它将放弃,而不是无限期地等待。这种机制对于避免死锁和提高系统的响应性非常有用
try_lock_for(duration): 这个方法允许线程尝试在指定的时间段内获取锁。如果在这段时间内锁未被获取,则返回 false
。这里的 duration
是一个表示时间长度的对象,比如可以使用 std::chrono
库来指定
try_lock_for
是 std::timed_mutex
或类似互斥体(如 std::recursive_timed_mutex
)的一个成员函数,它尝试在指定时间段内获取锁。如果在这个时间段内成功获得锁,它会返回 true
;如果时间段结束时仍未获得锁,它会返回 false
。这种机制允许线程不会无限期地等待锁的释放,提高了程序的响应性和灵活性。
共享锁(Shared Lock),在多线程编程和数据库管理系统中,是一种用于控制对共享资源的并发访问的同步机制。与互斥锁(独占锁)不同,共享锁允许多个线程或进程同时读取同一资源,但在写入时仍然需要独占访问权限。
lock_shared()
函数用于获取共享锁,也称为读锁。当你希望多个线程能够同时读取某个共享数据时使用。在任何时刻,可以有多个线程持有共享锁,只要没有线程持有独占锁。这允许多个读操作并行执行,而不会互相冲突,因为读操作通常不会改变数据状态。
lock()
函数用于获取独占锁,也称为写锁。当你希望确保只有一个线程能够写入或修改共享数据时使用。独占锁保证了没有其他线程可以同时读取或写入共享资源,确保了对共享资源的独占访问权。
#include <thread>
#include <iostream>
#include <string>
#include <mutex>
#include <shared_mutex>
//Linux -lpthread
using namespace std;
// RAII
class XMutex
{
public:
XMutex(mutex& mux):mux_(mux)
{
cout << "Lock" << endl;
mux.lock();
}
~XMutex()
{
cout << "Unlock" << endl;
mux_.unlock();
}
private:
mutex& mux_;
};
static mutex mux;
void TestMutex(int status)
{
XMutex lock(mux);
if (status == 1)
{
cout << "=1" << endl;
return;
}
else
{
cout << "!=1" << endl;
return;
}
}
int main(int argc, char* argv[])
{
TestMutex(1);
TestMutex(2);
getchar();
return 0;
}
std::lock_guard
是 C++ 标准库中的一个模板类,用于简化互斥锁(如 std::mutex
)的管理。它实现了一种被称为“范围锁定”(RAII, Resource Acquisition Is Initialization)的模式,确保在持有锁的线程的执行范围内,锁一定会被持有,并在范围结束时自动释放。
#include <thread>
#include <iostream>
#include <string>
#include <mutex>
#include <shared_mutex>
//Linux -lpthread
using namespace std;
// RAII
class XMutex
{
public:
XMutex(mutex& mux):mux_(mux)
{
cout << "Lock" << endl;
mux.lock();
}
~XMutex()
{
cout << "Unlock" << endl;
mux_.unlock();
}
private:
mutex& mux_;
};
static mutex mux;
void TestMutex(int status)
{
XMutex lock(mux);
if (status == 1)
{
cout << "=1" << endl;
return;
}
else
{
cout << "!=1" << endl;
return;
}
}
static mutex gmutex;
void TestLockGuard(int i)
{
gmutex.lock();
{
//�?�?��������lock
lock_guard<mutex> lock(gmutex,adopt_lock);
//�����?���
}
{
lock_guard<mutex> lock(gmutex);
cout << "begin thread " << i << endl;
}
for (;;)
{
{
lock_guard<mutex> lock(gmutex);
cout << "In " << i << endl;
}
this_thread::sleep_for(500ms);
}
}
int main(int argc, char* argv[])
{
for (int i = 0; i < 3; i++)
{
thread th(TestLockGuard, i + 1);
th.detach();
}
TestMutex(1);
TestMutex(2);
getchar();
return 0;
}
在 C++ 中的多线程编程里,锁的标签(或锁策略标签)是一些用于指定锁的行为的标记。这些标签通常与锁管理器(如 std::unique_lock
或 std::lock_guard
)一起使用,来控制互斥量的锁定和解锁行为。以下是一些常见的锁的标签:
std::adopt_lock
: 这个标签用于指示锁管理器对象,互斥量在传递给锁管理器之前已经被当前线程锁定。锁管理器将“采用”这个已经存在的锁,并在其析构时释放它。使用 std::adopt_lock
需要确保互斥量在传递之前已经被锁定。
std::defer_lock
: 使用这个标签创建的锁管理器对象不会立即锁定互斥量。这允许延迟锁定操作,直到显式调用锁定方法。这提供了更多的控制,允许在需要时进行锁定。
std::try_to_lock
: 用这个标签构造的锁管理器会尝试锁定互斥量,但不会阻塞等待。如果互斥量当前不可用(已被其他线程锁定),锁管理器不会持有锁。
std::scoped_lock
是 C++17 标准引入的一个锁管理器,用于简化多个互斥锁的获取和释放,从而帮助避免死锁。它是一种作用域锁(scope-based locking),能够在构造时自动获取一个或多个互斥锁,并在离开作用域(即对象被销毁)时自动释放这些锁。
#include <thread>
#include <iostream>
#include <mutex>
#include <list>
#include <string>
#include <sstream>
using namespace std;
list<string> msgs_;
mutex mux;
condition_variable cv;
void ThreadWrite() {
for (int i = 0;; i++) {
stringstream ss;
ss << "Write msg" << i;
unique_lock<mutex>lock(mux);
msgs_.push_back(ss.str());
cv.notify_one();
this_thread::sleep_for(3s);
}
}
void ThreadRead(int i) {
while (true) {
unique_lock<mutex>lock(mux);
cout << "read msg" << endl;
cv.wait(lock, [i] {
cout << i << "wait" << endl;
return !msgs_.empty();
});
}
while (!msgs_.empty()) {
cout << i << "read" << msgs_.front() << endl;
msgs_.pop_front();
}
}
int main() {
}