我希望有人可以帮助我解决我需要修复的C程序中的一些不可预知的行为:
我有两个Xenomai实时任务(线程),等待它们从两个CAN总线之一接收传入消息。
每个任务调用一个函数checkMessageNumber()但是我得到了不可预测的结果。
请注意我使用的是基于优先级的单线程系统。一个线程优先于另一个线程,但是当另一个线程优先时,一个线程可以在执行期间执行。
未来有可能硬件可以升级到多线程系统,但是程序的这部分仍然只限于一个线程(一个CPU核心)。
据我所知,每个线程都会调用它自己的函数实例,所以我不知道发生了什么。
int getMessageIndex(unsigned int msg_number)
{
unsigned int i = 0;
while(i < global_number_message_boxes)
{
if (global_message_box[i].id == msg_number}
return i; // matched the msg number, so return the index number
i++;
}
return -1; // no match found
}
最初这个函数非常难以预测,当消息流入并由两个任务处理时(取决于消息来自哪个硬件总线),即使传入的“msg_number”确实匹配,此函数有时会返回-1 'global_message_box'结构中的'id'。
通过将'global_number_message_boxes'设置为整数,我能够更好地工作:
例如。 while(i < 50)
但是,即使应该匹配,函数仍然有时会返回-1。
我只是在阅读全局变量,为什么它们会被破坏?我需要了解什么?
我的想法是简化事情,以便传入的'msg_number'只是'global_message_box'中的'id'。
然后,每个线程将直接写入结构,而不必检查写入的“id”。
使用互斥锁有多重要?由于系统设计,每个线程永远不会写入结构的同一部分,所以我不确定它是否重要?
感谢。
答案 0 :(得分:3)
这可能归结为缺乏围绕全局结构的线程同步:你说这个函数只是读取。当然,但是如果另一个线程调用另一个写global_number_message_boxes
或global_message_box
的函数呢?在你有全局变量和多个线程访问它们的系统中,保险箱规则是:锁定每个访问。也许您使用的平台甚至支持读/写锁,因此只要没有人写,多个线程就可以同时读取。
答案 1 :(得分:1)
Lock和Semaphores将成为您的朋友。使用两个线程写入数据将导致任何数量的问题。
当线程进入该函数时,您将不得不阻塞其他线程并在退出时解除这些线程的阻塞。这将确保线程安全操作并产生一致的结果。