我在Qt上创建了一个C ++程序:
//CONNECT TO SERIAL 1
//CONNECT TO DATABASE
while(true)
{
query.exec("SELECT id, phone, message FROM USERS WHERE codesend=0 LIMIT 0,1");
if (query.next())
{
int id = query.value(0).toInt();
// Update database: SET "SEND" to 1
query.prepare("UPDATE USERS SET codesend=1 WHERE ID= :nid");
query.bindValue(":nid", id);
query.exec();
//SEND SMS, I DONT DISPLAY IT THATS NOT THE PROBLEM
}
}
这很有效!
问题是:
我有很多能够发送短信的串口,在上面的代码中我只用了一个。
目前我使用其中2个。我复制并粘贴此代码并运行2个程序。唯一的区别是它们连接到另一个串口。 - 他们连接到同一个数据库 -
使用3个程序连接到3个串行端口时的问题是有时它会发送2次sms,因为SELECT
和UPDATE
之间的时间太长。
EX:
计划1 select
,计划2 select
,计划1 update
...已太晚的计划2已经选择并将发送...
我该如何解决?
答案 0 :(得分:2)
快速修复,只有一个程序调用数据库,然后将数据传递给其他人。
但由于进程间通信困难和同步,这很难,而是可以在一个程序中使用线程。
概念计划
std::mutex mtx;
Data GetSelect() {
std::lock_guard<std::mutex> lck (mtx); // insure mutual exclusive with RAII
query.exec("SELECT id, phone, message FROM USERS WHERE codesend=0 LIMIT 0,1");
if (query.next()) {
int id = query.value(0).toInt();
// Update database: SET "SEND" to 1
query.prepare("UPDATE USERS SET codesend=1 WHERE ID= :nid");
query.bindValue(":nid", id);
query.exec();
... put query in data
return data;
}
return EndToken;
}
// function called by thread
void SendSMS(int SerialPort) {
//CONNECT TO SERIAL SerialPort
auto data = GetSelect();
while(data != EndToken) {
//SEND SMS, I DONT DISPLAY IT THATS NOT THE PROBLEM
data = GetSelect();
}
}
int main() {
//CONNECT TO DATABASE
// make and start threads with different serial ports.
return EXIT_SUCCESS;
}
更雄心勃勃的目标可能是将所有调制解调器用于所有查询,执行此操作的方法是查找线程安全队列,将单个结果/记录放入列表中,并让某些工作线程从列表中消耗。 / p>
答案 1 :(得分:1)
在数据库中的表上使用LOCK
。这样,只有一个应用程序可以一次查询数据库,其他应用程序将阻止,直到允许他们阅读。
mysql> LOCK TABLES USERS WRITE
完成工作后(更新后)解锁后使用:
mysql> UNLOCK TABLES
答案 2 :(得分:0)
我想,你执行AT命令来发送短信,可能打开/关闭连接到串口的调制解调器。在这种情况下,为什么不解决来自另一个POV的问题并使用Surt提出的多线程方法?
您只需执行一个程序即可管理所有不同的串口。线程可以为单个发送生成,或者(在我看来更好)编码为主线程的“短信发送服务”。在任何一种情况下,它都是执行select和update命令的主线程(尽管线程已发送其指定的sms)。
查看QT Concurrent,QThread和QRunnable,或者只是将串行端口/调制解调器处理程序定义为类,然后move it to a thread。信号槽可以用来传输要发送的短信并取回发送的结果。
希望这有帮助!