Ik wil graag gebruik maken van een lockfree queue. Momenteel maak ik gebruik van boost::lockfree::queue (en spsc_queue). Echter vereist boost::lockfree::queue types met een copy-constructor, een trivial assignment-operator en een trivial destructor. Een groot aantal types voldoet daar natuurlijk niet aan. In mijn geval gaat het vooral om std::string. Nu heb ik dit opgelost door pointers naar strings op te slaan in de queue. Ik stuitte voor zover niet op problemen, maar ik heb dit momenteel alleen getest in een single-consumer/single-producer scenario.
Om het één en ander eenvoudiger te maken heb ik zelf een wrapper-class geschreven.
Volgens dit artikel is het echter niet mogelijk om de data in een thread-veilige manier te verwijderen. Kan iemand mij duidelijk uitleggen waar eventuele gevaren schuilen of heeft iemand een linkje met een goede uitleg? Zijn er nog alternatieve mogelijkheden (buiten zelf synchronisatie toepassen) als het daadwerkelijk niet thread-veilig is?
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| boost::lockfree::queue<std::string*> queue_(64); void producer() { std::string* str = new std::string("hai"); while (!queue_.bounded_push(str)); } void consumer() { std::string* str; while(queue_.pop(str)) { // doe wat met str delete str; } } |
Om het één en ander eenvoudiger te maken heb ik zelf een wrapper-class geschreven.
C++:
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
| template<typename T> class ptr_queue { public: typedef T value_type ; typedef boost::lockfree::queue<value_type*> queue_type; ptr_queue(std::size_t size = 64) : queue_(size) { } bool push(const value_type& value) { value_type* new_value = new value_type(value); return queue_.bounded_push(new_value); } bool pop(value_type& value) { value_type* value_ptr; bool ret = queue_.pop(value_ptr); if(ret) { value = *value_ptr; delete value_ptr; } return ret; } bool empty() const { return queue_.empty(); } private: queue_type queue_; }; ptr_queue<std::string> queue_(64); void producer() { std::string("hai"); while (!queue_.bounded_push(str)); } void consumer() { std::string str; while(queue_.pop(str)) { // doe wat met str } } |
Volgens dit artikel is het echter niet mogelijk om de data in een thread-veilige manier te verwijderen. Kan iemand mij duidelijk uitleggen waar eventuele gevaren schuilen of heeft iemand een linkje met een goede uitleg? Zijn er nog alternatieve mogelijkheden (buiten zelf synchronisatie toepassen) als het daadwerkelijk niet thread-veilig is?
PC load letter? What the fuck does that mean?