Bonjour,

J'ai développé une application multithreadée où chaque thread va lire des informations dans un fichier (un fichier par thread) toutes les 5 secondes.
Et je me suis rendu compte qu'il y a un problème d'affichage de mes logs lorsque le fichier n'existe pas et qu'une exception est levée. En effet, les logs des threads s'affichent parfois sur la même ligne ou le contenu du message ne s'affiche pas. Ce qui me fait penser que mon code n'est pas Thread Safe.
Dans le résultat d'execution de mon code, j'ai volontairement lancé 3 threads sur 3 fichiers qui n'existe pas :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
2014-01-28 21:19:42,369 ERROR [0x7fbaf6a6f700:null] - Probe Reading Failed : The Probe 'F1.txt' is not readable.
2014-01-28 21:19:42,369 ERROR [0x7fbaf7270700:null] - Probe Reading Failed : The Probe 'F2.txt' is not readable.
2014-01-28 21:19:42,369 ERROR [0x7fbaf626e700:null] - 
 
2014-01-28 21:19:47,370 ERROR [0x7fbaf6a6f700:null] - 2014-01-28 21:19:47,370 ERROR [0x7fbaf626e700:null] - Unknown Probe Type : The Probe 'B1.txt' is unknown.
2014-01-28 21:19:47,370 ERROR [0x7fbaf7270700:null] - Probe Reading Failed : The Probe 'F2.txt' is not readable.
2014-01-28 21:19:52,370 ERROR [0x7fbaf6a6f700:null] - Probe Reading Failed : The Probe 'F1.txt' is not readable.
2014-01-28 21:19:52,370 ERROR [0x7fbaf626e700:null] - Unknown Probe Type : The Probe 'B1.txt' is unknown.
2014-01-28 21:19:52,370 ERROR [0x7fbaf7270700:null] - Probe Reading Failed : The Probe 'F2.txt' is not readable.
J'utilise log4cxx pour loggger et on voit à la ligne 3 et 5 des logs vides.

J'ai aussi utilisé le std::cout afin d'écarter log4cxx. Je n'ai pas le même résultat mais j'ai eu le même genre de comportement sur le premier affichage :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
Unknown Probe Type : The Probe 'B1.txt' is unknown.Probe Reading Failed : The Probe 'F1.txt' is not readable.Probe Reading Failed : The Probe 'F2.txt' is not readable.
 
 
Unknown Probe Type : The Probe 'B1.txt' is unknown.
Probe Reading Failed : The Probe 'F1.txt' is not readable.
Probe Reading Failed : The Probe 'F2.txt' is not readable.
Unknown Aquade Probe Type : The Probe 'B1.txt' is unknown.
Probe Reading Failed : The Probe 'F2.txt' is not readable.
Probe Reading Failed : The Probe 'F1.txt' is not readable.
Je n'arrive pas à identifier d'où vient exactement le problème. Je me demande si ça ne vient pas de mon exception mais j'ai aucune certitude.

Classe CustomException
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class CustomException : public std::exception
{
protected:
	/**
         * The name of the exception
         */
	std::string m_name;
 
	/**
         * The description of the exception
         */
	std::string m_description;
 
public:
	CustomException(std::string name, std::string description) noexcept;
 
	virtual ~CustomException();
 
	virtual const char * what() noexcept
	{
		std::stringstream ss;
		ss << m_name << " : " << m_description;
		return ss.str().c_str();
	}
};
Classe qui traite un fichier
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
class CustomProcess
{
protected:
	std::string m_filePath;
public:
 
	explicit CustomProcess(std::string filePath)
	: m_filePath(filePath)
	{
 
	}
 
	void operator()()
	{
		while (true)
		{
			try
			{
				try
				{
					getData();
				}
				catch(CustomException& e)
				{
					LOG4CXX_ERROR(classLogger, e.what());
				}
 
				boost::this_thread::sleep(boost::posix_time::seconds(5));
 
				// Make sure we can be interrupted
				boost::this_thread::interruption_point();
			}
			catch(const boost::thread_interrupted&)
			{
				LOG4CXX_INFO(classLogger, "Thread interrupted");
				break;
			}
		}
	}
 
	void getData() throw(CustomException)
	{
		float value = 0.0;
 
		if(!m_filePath.at(0) == 'F')
		{
			std::ifstream ifs(m_filePath);
			if(!ifs.fail())
			{
				static const boost::regex temperatureRegex("([0-9a-fA-F]{2}[ ]){9}t=([0-9]+)");
 
				std::string line;
				while(getline(ifs, line))
				{
					boost::smatch match;
					if(boost::regex_match(line, match,temperatureRegex))
					{
						std::string temperatureValue = std::string() + match[2];
						value = atoi(temperatureValue.c_str());
						value /= 1000;
						break;
					}
				}
				if(value == 0.0)
				{
					std::stringstream description;
					description << "The Probe " << m_filePath << " has not a correct value.";
					throw CustomException("Probe Reading Failed", description.str());
				}
			}
			else
			{
				std::stringstream description;
				description << "The Probe '" <<m_filePath << "' is not readable.";
				throw CustomException("Probe Reading Failed", description.str());
			}
		}
		else
		{
			std::stringstream description;
			description << "The Probe'" << m_filePath << "' is unknown.";
			throw CustomException("Unknown Probe Type", description.str());
		}
 
		...
	}
};
Le main qui lance les threads
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
std::list<string> fileList= ....;
 
boost::thread_group customProcessThreadGroup;
std::list<string>::iterator it;
for(it = fileList.begin(); it != fileList.end(); ++it)
{
	CustomProcess customProcess(*it);
	customProcessThreadGroup.create_thread(customProcess);
}
 
customProcessThreadGroup.join_all();