// #pragma once #include #include "IODeviceWithSCF.tlh" //----------------------------------------------------------------------------- // IODeviceWithSCF //----------------------------------------------------------------------------- namespace DIOS::Dev::Detail { template void IODriverWithSCF ::Prepare () { super::Prepare (); assert (m_SCFDllName.length ()); m_SCF = nsSCF::SCF::FromDLL (m_SCFDllName.c_str ()); m_SCF.OnPassiveDisconnected = [ this ] () { this->EventCenter->OnPassiveDisconnected(); this->OnNewPacket.Set(); }; m_SCF.Queue.OnNewPacket = [ this ] () { this->OnNewPacket.Set (); }; } template bool IODriverWithSCF ::Connect () { auto THReadPacket = [ this ] () { auto msWait = std::chrono::milliseconds (m_msWaitSCFTimeOut); while (true) { //mLog::Info("THReadPacket: begin wait"); auto rc = OnNewPacket.Wait (msWait); //mLog::Info("THReadPacket: end wait"); if (! m_SCF.isConnected ()) return ; if (! rc) continue; // 等待超时 if (!m_SCF.isConnected ()) return; while (true) // 有数据到达, 全部读完, 然后等待下一个事件 { if (!m_SCF.isConnected ()) return; if (m_SCF.Queue.isEmpty ()) break; char cMsg [CMD_LEN_MAX]; memset (cMsg, 0, sizeof (cMsg)); int PacketLength = CMD_LEN_MAX; int len = m_SCF.Queue.Dequeue (cMsg, PacketLength, 20); if (len > 0) Dequeue (cMsg, len); } } }; auto THFunc = [this, THReadPacket] () { THReadPacket (); m_TID = decltype (m_TID) (); // ! 记得在这里复位 ThreadID }; int res = true; auto TH = std::thread(THFunc); if (THREAD_PRIORITY_NORMAL != m_nPriority) { res = SetThreadPriority(TH.native_handle(), m_nPriority); } if (m_TID == decltype (m_TID) ()) { m_TID = TH.get_id (); TH.detach (); } m_SCF.DecodePack(isActDecodeFun); return res; } template void IODriverWithSCF ::Disconnect () { m_SCF.Disconnect (); OnNewPacket.Set (); super::Disconnect (); } template bool IODriverWithSCF::DecodePack(bool action) { isActDecodeFun = action; return isActDecodeFun; } template void IODriverWithSCF::SetThread_Priority(int level) { // 优先级范围从-2到15,7是默认优先级 m_nPriority = level; } // 函数: SetThread_Affinity(const std::vector& cpus) // 描述: 设置线程的CPU亲和性 // 参数: cpus - 要绑定的CPU核心序列 // 返回值: 无 template void IODriverWithSCF::SetThread_Affinity(const std::vector& cpus) { unsigned int num_cores = std::thread::hardware_concurrency(); if (num_cores == 0) { throw std::runtime_error("Failed to determine the number of available cores."); } #ifdef _WIN32 DWORD_PTR mask = 0; for (const auto& cpu : cpus) { if (cpu < 0 || static_cast(cpu) >= num_cores) { throw std::runtime_error("Invalid core number specified."); } mask |= (1 << cpu); } DWORD_PTR result = SetThreadAffinityMask(m_ThreadHandle, mask); if (result == 0) { throw std::runtime_error("Failed to set thread CPU affinity."); } #else cpu_set_t cpuset; CPU_ZERO(&cpuset); for (const auto& cpu : cpus) { if (cpu < 0 || static_cast(cpu) >= num_cores) { throw std::runtime_error("Invalid core number specified."); } CPU_SET(cpu, &cpuset); } int result = pthread_setaffinity_np(m_ThreadHandle, sizeof(cpu_set_t), &cpuset); if (result != 0) { throw std::runtime_error("Failed to set thread CPU affinity."); } #endif } template bool IODriverWithSCF ::isConnected () const { return m_SCF.isConnected (); } }