linux 编译
This commit is contained in:
@@ -16,158 +16,165 @@
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <string_view>
|
||||
|
||||
namespace Psc {
|
||||
|
||||
bool check_if_shared_memory_exists(std::string_view name) {
|
||||
int fd = shm_open(name.c_str(), O_RDWR, 0777);
|
||||
if (fd < 0) {
|
||||
return false;
|
||||
}
|
||||
close(fd);
|
||||
return true;
|
||||
}
|
||||
Shared_Memory::~Shared_Memory() { close(); }
|
||||
bool Shared_Memory::create(std::string_view name, size_t size) {
|
||||
m_name = name;
|
||||
m_size = size;
|
||||
m_fd = shm_open(name.c_str(), O_CREAT | O_RDWR, 0777);
|
||||
if (m_fd < 0)
|
||||
return false;
|
||||
if (ftruncate(m_fd, size) != 0)
|
||||
return false;
|
||||
m_ptr = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, m_fd, 0);
|
||||
if (fchmod(m_fd, 0777) != 0) {
|
||||
std::cerr << "修改共享内存权限失败: " << get_error_message() << std::endl;
|
||||
Psc::fail_fast();
|
||||
}
|
||||
return m_ptr != MAP_FAILED;
|
||||
}
|
||||
bool Shared_Memory::open(std::string_view name, size_t size) {
|
||||
m_name = name;
|
||||
m_size = size;
|
||||
m_fd = shm_open(name.c_str(), O_RDWR, 0777);
|
||||
if (m_fd < 0)
|
||||
return false;
|
||||
m_ptr = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, m_fd, 0);
|
||||
return m_ptr != MAP_FAILED;
|
||||
}
|
||||
void Shared_Memory::close() {
|
||||
// if (m_ptr) {
|
||||
// munmap(m_ptr, m_size);
|
||||
// m_ptr = nullptr;
|
||||
// }
|
||||
if (m_fd >= 0) {
|
||||
::close(m_fd);
|
||||
m_fd = -1;
|
||||
}
|
||||
}
|
||||
void Shared_Memory::unlink() {
|
||||
if (!m_name.empty())
|
||||
shm_unlink(m_name.c_str());
|
||||
}
|
||||
|
||||
struct MutexBlock {
|
||||
pthread_mutex_t mutex;
|
||||
std::atomic<int> initialized; // 0 = 未初始化, 1 = 初始化完成
|
||||
};
|
||||
|
||||
Cross_Process_Mutex::Cross_Process_Mutex() {}
|
||||
|
||||
void Cross_Process_Mutex::init(std::string_view mutexName) {
|
||||
this->m_mutexName = mutexName;
|
||||
bool creator = false;
|
||||
|
||||
// 第一次创建尝试 O_EXCL,能判断是否首次创建
|
||||
m_fd = shm_open(m_mutexName.c_str(), O_RDWR | O_CREAT | O_EXCL, 0777);
|
||||
if (m_fd >= 0) {
|
||||
creator = true;
|
||||
if (ftruncate(m_fd, sizeof(MutexBlock)) < 0) {
|
||||
std::cout << "跨进程锁" << mutexName << "创建失败 ["
|
||||
<< get_error_message() << "] " << LOG_POS << std::endl;
|
||||
Psc::fail_fast();
|
||||
bool check_if_shared_memory_exists(std::string_view name) {
|
||||
std::string shm_name(name);
|
||||
int fd = shm_open(shm_name.c_str(), O_RDWR, 0777);
|
||||
if (fd < 0) {
|
||||
return false;
|
||||
}
|
||||
close(fd);
|
||||
return true;
|
||||
}
|
||||
|
||||
Shared_Memory::~Shared_Memory() { close(); }
|
||||
|
||||
bool Shared_Memory::create(std::string_view name, size_t size) {
|
||||
m_name = name;
|
||||
m_size = size;
|
||||
std::string shm_name(name);
|
||||
m_fd = shm_open(shm_name.c_str(), O_CREAT | O_RDWR, 0777);
|
||||
if (m_fd < 0)
|
||||
return false;
|
||||
if (ftruncate(m_fd, size) != 0)
|
||||
return false;
|
||||
m_ptr = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, m_fd, 0);
|
||||
if (fchmod(m_fd, 0777) != 0) {
|
||||
std::cerr << "修改共享内存权限失败: " << get_error_message() << LOG_POS
|
||||
<< std::endl;
|
||||
std::cerr << "修改共享内存权限失败: " << get_error_message() << std::endl;
|
||||
Psc::fail_fast();
|
||||
}
|
||||
} else if (errno == EEXIST) {
|
||||
// 已经存在,只打开,不改大小
|
||||
m_fd = shm_open(m_mutexName.c_str(), O_RDWR, 0777);
|
||||
if (m_fd < 0) {
|
||||
std::cout << "跨进程锁" << mutexName << "打开失败 ["
|
||||
<< get_error_message() << "] " << LOG_POS << std::endl;
|
||||
return m_ptr != MAP_FAILED;
|
||||
}
|
||||
|
||||
bool Shared_Memory::open(std::string_view name, size_t size) {
|
||||
m_name = name;
|
||||
m_size = size;
|
||||
std::string shm_name(name);
|
||||
m_fd = shm_open(shm_name.c_str(), O_RDWR, 0777);
|
||||
if (m_fd < 0)
|
||||
return false;
|
||||
m_ptr = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, m_fd, 0);
|
||||
return m_ptr != MAP_FAILED;
|
||||
}
|
||||
|
||||
void Shared_Memory::close() {
|
||||
// if (m_ptr) {
|
||||
// munmap(m_ptr, m_size);
|
||||
// m_ptr = nullptr;
|
||||
// }
|
||||
if (m_fd >= 0) {
|
||||
::close(m_fd);
|
||||
m_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void Shared_Memory::unlink() {
|
||||
if (!m_name.empty())
|
||||
shm_unlink(m_name.c_str());
|
||||
}
|
||||
|
||||
struct MutexBlock {
|
||||
pthread_mutex_t mutex;
|
||||
std::atomic<int> initialized; // 0 = 未初始化, 1 = 初始化完成
|
||||
};
|
||||
|
||||
Cross_Process_Mutex::Cross_Process_Mutex() {
|
||||
}
|
||||
|
||||
void Cross_Process_Mutex::init(std::string_view mutexName) {
|
||||
this->m_mutexName = mutexName;
|
||||
bool creator = false;
|
||||
|
||||
// 第一次创建尝试 O_EXCL,能判断是否首次创建
|
||||
m_fd = shm_open(m_mutexName.c_str(), O_RDWR | O_CREAT | O_EXCL, 0777);
|
||||
if (m_fd >= 0) {
|
||||
creator = true;
|
||||
if (ftruncate(m_fd, sizeof(MutexBlock)) < 0) {
|
||||
std::cout << "跨进程锁" << mutexName << "创建失败 ["
|
||||
<< get_error_message() << "] " << LOG_POS << std::endl;
|
||||
Psc::fail_fast();
|
||||
}
|
||||
if (fchmod(m_fd, 0777) != 0) {
|
||||
std::cerr << "修改共享内存权限失败: " << get_error_message() << LOG_POS
|
||||
<< std::endl;
|
||||
Psc::fail_fast();
|
||||
}
|
||||
} else if (errno == EEXIST) {
|
||||
// 已经存在,只打开,不改大小
|
||||
m_fd = shm_open(m_mutexName.c_str(), O_RDWR, 0777);
|
||||
if (m_fd < 0) {
|
||||
std::cout << "跨进程锁" << mutexName << "打开失败 ["
|
||||
<< get_error_message() << "] " << LOG_POS << std::endl;
|
||||
Psc::fail_fast();
|
||||
}
|
||||
} else {
|
||||
std::cout << "跨进程锁" << mutexName << "检测失败 [" << get_error_message()
|
||||
<< "] " << LOG_POS << std::endl;
|
||||
Psc::fail_fast();
|
||||
}
|
||||
} else {
|
||||
std::cout << "跨进程锁" << mutexName << "检测失败 [" << get_error_message()
|
||||
<< "] " << LOG_POS << std::endl;
|
||||
Psc::fail_fast();
|
||||
}
|
||||
|
||||
// 映射
|
||||
m_addr = mmap(nullptr, sizeof(MutexBlock), PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
m_fd, 0);
|
||||
if (m_addr == MAP_FAILED) {
|
||||
std::cout << "跨进程锁" << mutexName << "mmap失败 [" << get_error_message()
|
||||
<< "] " << LOG_POS << std::endl;
|
||||
Psc::fail_fast();
|
||||
}
|
||||
// 映射
|
||||
m_addr = mmap(nullptr, sizeof(MutexBlock), PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
m_fd, 0);
|
||||
if (m_addr == MAP_FAILED) {
|
||||
std::cout << "跨进程锁" << mutexName << "mmap失败 [" << get_error_message()
|
||||
<< "] " << LOG_POS << std::endl;
|
||||
Psc::fail_fast();
|
||||
}
|
||||
|
||||
auto block = static_cast<MutexBlock *>(m_addr);
|
||||
auto block = static_cast<MutexBlock *>(m_addr);
|
||||
|
||||
if (creator) {
|
||||
// 创建者初始化
|
||||
memset(&block->mutex, 0, sizeof(pthread_mutex_t));
|
||||
block->initialized.store(0, std::memory_order_relaxed);
|
||||
if (creator) {
|
||||
// 创建者初始化
|
||||
memset(&block->mutex, 0, sizeof(pthread_mutex_t));
|
||||
block->initialized.store(0, std::memory_order_relaxed);
|
||||
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
|
||||
pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST);
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
|
||||
pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST);
|
||||
|
||||
if (pthread_mutex_init(&block->mutex, &attr) != 0) {
|
||||
if (pthread_mutex_init(&block->mutex, &attr) != 0) {
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
std::cout << "跨进程锁" << mutexName << "init失败 ["
|
||||
<< get_error_message() << "] " << LOG_POS << std::endl;
|
||||
Psc::fail_fast();
|
||||
}
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
std::cout << "跨进程锁" << mutexName << "init失败 ["
|
||||
<< get_error_message() << "] " << LOG_POS << std::endl;
|
||||
Psc::fail_fast();
|
||||
}
|
||||
pthread_mutexattr_destroy(&attr);
|
||||
|
||||
block->initialized.store(1, std::memory_order_release);
|
||||
|
||||
} else {
|
||||
// 后来者等待初始化完成
|
||||
auto ib = &block->initialized;
|
||||
while (ib->load(std::memory_order_acquire) != 1) {
|
||||
sched_yield();
|
||||
block->initialized.store(1, std::memory_order_release);
|
||||
} else {
|
||||
// 后来者等待初始化完成
|
||||
auto ib = &block->initialized;
|
||||
while (ib->load(std::memory_order_acquire) != 1) {
|
||||
sched_yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Cross_Process_Mutex::~Cross_Process_Mutex() {
|
||||
// if (m_addr) munmap(m_addr, sizeof(MutexBlock));
|
||||
//
|
||||
close(m_fd);
|
||||
}
|
||||
|
||||
void Cross_Process_Mutex::lock() {
|
||||
auto block = static_cast<MutexBlock *>(m_addr);
|
||||
int r = pthread_mutex_lock(&block->mutex);
|
||||
|
||||
if (r == EOWNERDEAD) {
|
||||
pthread_mutex_consistent(&block->mutex);
|
||||
} else if (r == ENOTRECOVERABLE) {
|
||||
throw std::runtime_error("mutex not recoverable");
|
||||
} else if (r != 0) {
|
||||
throw std::runtime_error("pthread_mutex_lock failed");
|
||||
Cross_Process_Mutex::~Cross_Process_Mutex() {
|
||||
// if (m_addr) munmap(m_addr, sizeof(MutexBlock));
|
||||
//
|
||||
close(m_fd);
|
||||
}
|
||||
}
|
||||
|
||||
void Cross_Process_Mutex::unlock() {
|
||||
auto block = static_cast<MutexBlock *>(m_addr);
|
||||
pthread_mutex_unlock(&block->mutex);
|
||||
}
|
||||
void Cross_Process_Mutex::lock() {
|
||||
auto block = static_cast<MutexBlock *>(m_addr);
|
||||
int r = pthread_mutex_lock(&block->mutex);
|
||||
|
||||
if (r == EOWNERDEAD) {
|
||||
pthread_mutex_consistent(&block->mutex);
|
||||
} else if (r == ENOTRECOVERABLE) {
|
||||
throw std::runtime_error("mutex not recoverable");
|
||||
} else if (r != 0) {
|
||||
throw std::runtime_error("pthread_mutex_lock failed");
|
||||
}
|
||||
}
|
||||
|
||||
void Cross_Process_Mutex::unlock() {
|
||||
auto block = static_cast<MutexBlock *>(m_addr);
|
||||
pthread_mutex_unlock(&block->mutex);
|
||||
}
|
||||
} // namespace Psc
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user