#include <iostream>
#include <queue>
#include <optional>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>
#include <string>
struct DataInfo {
DataInfo() = default;
DataInfo(const std::string& accountNum, const std::string& systemId, const std::string& passWord, const std::string& channelType)
: accountNum(accountNum), systemId(systemId), passWord(passWord), channelType(channelType) {}
std::string accountNum{};
std::string systemId{};
std::string passWord{};
std::string channelType{};
};
struct SendData {
SendData() = default;
std::optional<DataInfo> dataInfo;
bool quitFlag;
};
std::mutex mtx;
std::condition_variable cv;
std::queue<SendData> que;
std::optional<DataInfo> getInputData()
{
std::cout << "Please input data:"<< std::endl;
std::string input = "quit";
std::cin >> input;
if (input == "quit") {
return std::nullopt;
}
auto accountNumIndex = input.find_first_of(",");
std::string accountNum= input.substr(0,accountNumIndex);
input = input.substr(accountNumIndex+1,input.length());
auto systemIdIndex = input.find_first_of(",");
std::string systemId= input.substr(0,systemIdIndex);
input = input.substr(systemIdIndex+1,input.length());
auto passWordIndex = input.find_first_of(",");
std::string passWord= input.substr(0,passWordIndex);
input = input.substr(passWordIndex+1,input.length());
auto channelTypeIndex = input.find_first_of(",");
std::string channelType= input.substr(0,channelTypeIndex);
input = input.substr(channelTypeIndex+1,input.length());
DataInfo dataInfo{accountNum,systemId,passWord,channelType};
return std::make_optional(dataInfo);
}
void printfInputData(std::optional<DataInfo> data)
{
if(data != std::nullopt) {
std::cout << data.value().accountNum << std::endl;
std::cout << data.value().systemId << std::endl;
std::cout << data.value().passWord << std::endl;
std::cout << data.value().channelType << std::endl;
}
}
void senderFunc()
{
while(true) {
std::unique_lock<std::mutex> lk(mtx);
if(!que.empty()) {
if( cv.wait_for(lk,std::chrono::seconds(6)) == std::cv_status::timeout) {
std::cout << "senderFunc timeout." << std::endl;
}
}
auto dataInfo = getInputData();
SendData sendData{};
if(dataInfo != std::nullopt) {
sendData.quitFlag = false;
}
else {
sendData.quitFlag = true;
}
sendData.dataInfo = dataInfo;
que.push(sendData);
std::cout << "senderFunc send input data." << std::endl;
cv.notify_one();
if(sendData.quitFlag) {
std::cout << "senderFunc quit." << std::endl;
break;
}
}
}
void receiverRunc()
{
while (true) {
std::unique_lock<std::mutex> lk(mtx);
std::cout << "receiverRunc waiting." << std::endl;
cv.wait(lk,[]{return !que.empty();});
std::cout << "receive input data." << std::endl;
auto data = que.front();
que.pop();
// 处理数据需要较多时间,所以先解锁mutex
lk.unlock();
if(data.quitFlag) {
std::cout << "receiverRunc quit." << std::endl;
break;
}
std::cout << "process input data." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(4));
printfInputData(data.dataInfo);
cv.notify_one();
}
}
int main()
{
std::cout << "main" << std::endl;
std::thread thd1(senderFunc);
std::thread thd2(receiverRunc);
thd1.join();
thd2.join();
return 0;
}