我希望为在freeRTOS环境中运行的3个线程生成随机值。我知道rand()不是线程安全的,所以我使用了一个mutex来保护它。此外,我只调用了一次srand()。在尝试解决这个问题时,我应该考虑什么?
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "FreeRTOS.h"
#include "semphr.h"
#include "sensorDriver.h"
SemaphoreHandle_t semaphoreMutexDriver;
uint16_t sensorValue;
void sensorDriver_initialize()
{
srand(time(NULL));
semaphoreMutexDriver = xSemaphoreCreateMutex();
}
void getValue()
{
if (xSemaphoreTake(semaphoreMutexDriver, portMAX_DELAY))
{
sensorValue = (uint16_t)(rand() % 50);
xSemaphoreGive(semaphoreMutexDriver);
}
}
uint16_t sensorDriver_getValue()
{
getValue();
return sensorValue;
}
更多的代码可以根据要求添加。
更新1
试着把sensorValue做成函数的局部,这样。
uint16_t firstSensorDriver_getValue()
{
if (xSemaphoreTake(semaphoreMutexDriver, portMAX_DELAY))
{
uint16_t sensorValue = (uint16_t)(rand() % 50);
xSemaphoreGive(semaphoreMutexDriver);
return sensorValue;
}
}
没有做到这一点(如果有更好的实现建议,请不要犹豫),而且线程在得到值后会把它放到一个struct中,不知道这是否有帮助。每个线程在自己的结构体中)。
更新2
这里是结构,以及如何保存值。
struct firstSensor
{
uint16_t firstSensorValue;
EventGroupHandle_t meassureEventGroup;
EventGroupHandle_t dataReadyEventGroup;
};
void firstSensor_fetchSensorValue(FirstSensor self)
{
self->firstSensorValue = sensorDriver_getValue();
}
UPDATE 3
下面是第一个和第二个线程结构实现的例子。
#ifndef FIRSTSENSOR_H
#define FIRSTSENSOR_H
typedef struct firstSensor* FirstSensor;
FirstSensor firstSensor_create(UBaseType_t taskPriority, EventGroupHandle_t
eventGroupMeassure, EventGroupHandle_t eventGroupDataReady);
uint16_t firstSensor_getSensorValue(FirstSensor self);
void firstSensor_destroySensor(FirstSensor self);
#endif
同样的,第二个线程头和源文件。
#ifndef SECONDSENSOR_H
#define SECONDSENSOR_H
typedef struct secondSensor* SecondSensor;
SecondSensor secondSensor_create(UBaseType_t taskPriority, EventGroupHandle_t
eventGroupMeassure, EventGroupHandle_t eventGroupDataReady);
uint16_t secondSensor_getSensorValue(SecondSensor self);
void secondSensor_destroySensor(SecondSensor self);
#endif
和实施
struct secondSensor
{
uint16_t secondSensorValue;
EventGroupHandle_t meassureEventGroup;
EventGroupHandle_t dataReadyEventGroup;
};
void secondSensor_fetchSensorValue(SecondSensor self)
{
self->secondSensorValue = firstSensorDriver_getValue();
}
void secondSensor_task(void* instance)
{
EventBits_t eventBitsMeasure;
SecondSensor self = (SecondSensor*)instance;
for (;;)
{
eventBitsMeasure = xEventGroupWaitBits(self->meassureEventGroup, BIT_SECOND_SENSOR, pdTRUE, pdTRUE, portMAX_DELAY);
if ((eventBitsMeasure & BIT_SECOND_SENSOR) == BIT_SECOND_SENSOR)
{
secondSensor_fetchSensorValue(self);
xEventGroupSetBits(self->dataReadyEventGroup, BIT_SECOND_SENSOR);
}
}
}
更新4好吧,技术上来说,他们是随机的,每个emm,运行这么说,但他们是相同的在同一运行。下面左边的图片是我的小程序打印在右边的简单随机打印。
更新5
另一个奇怪的事情是,每次我运行这段代码时,我得到的数字序列都是一样的,就好像stand从来没有被调用过一样(即使它被调用了),即使我用time(NULL)+clock()作为srand()的种子,每次都应该是不同的。也许它可以帮助...
所以,不知道完全是为什么,但是,只有当srand()被调用3次(每次任务运行时,但在无限循环之外,所以它只运行一次,在xTaskCreate创建任务时提供的函数中),而不是在main()中只调用一次时,它才会工作。如果它在main()函数中只被调用一次,那么随机值就如同从未调用过srand()函数一样。我猜测(只是猜测,还没有任何证据),这是因为每个任务都有自己的栈。
谢谢大家协助排除故障......