- notify_one() called before the mutex is unlocked - 8 Updates
- polymorph? - 15 Updates
- Constructing const array out of constexpr function - 2 Updates
Shiyao Ma <i@introo.me>: Mar 21 09:06PM -0700 Hi, I often see code like this: std::mutex mut; std::conditional_variable cond; std::queue<int> qi; // producer void my_producer() { std::lock_guard<std::mutex> lg(mut); // do something on qi cond.notify_one(); } // consumer void my_consumer() { std::unqiue_lock<std::mutex> ul(mut); cond.wait(ul, []{return !qi.empty();}); // do something ul.unlock() } Note that when cond.notify_one() is called, the lock_guard still holds the mutex. So even cond.wait is wake up, it will soon be put to sleep. I am confused about the above code. Does the above code make sense? Regards. |
rapotkinnik@gmail.com: Mar 22 03:48AM -0700 вторник, 22 марта 2016 г., 7:06:55 UTC+3 пользователь Shiyao Ma написал: > So even cond.wait is wake up, it will soon be put to sleep. > I am confused about the above code. Does the above code make sense? > Regards. Hi, When cond.wait(...) is called mutex has unlocked. When some thread handle notify_one() and step out cond.wait() method mutex became locked again. sorry for my english!=) |
Shiyao Ma <i@introo.me>: Mar 22 07:48AM -0700 I might not clearly express my question. Say, in my original code sample, the producer is: // producer void my_producer() { std::lock_guard<std::mutex> lg(mut); // do something on qi cond.notify_one(); } But I think a better one would be: // producer void my_producer() { { std::lock_guard<std::mutex> lg(mut); // do something on qi } cond.notify_one(); } In the latter, when the `notify_one' is called, the `lg' has already unlocked the mutex, so cond.wait in the consumer can successfully get the mutex. However, the former one suffers the problem that when notify_one is called, the mutex has not been released by the lock guard. My question is, does the former and the latter make a difference? Seemingly they should, but I often see code written in the former form. Regards. |
"Fred.Zwarts" <F.Zwarts@KVI.nl>: Mar 22 04:31PM +0100 "Shiyao Ma" schreef in bericht news:5bba06b2-80a1-43d1-9e5a-ba073b7f8ead@googlegroups.com... >My question is, does the former and the latter make a difference? >Seemingly they should, but I often see code written in the former form. >Regards. The problem with the second method is that it creates a race condition. notify_one is called after unlocking the mutex. So, it is not known who (if any) has locked the mutex. It could be that the reason to call notif_one has disappeared because another thread has done something with qi already. In the first method, notif_one is called with the mutex locked, so immediately when it unlocks the mutex, one of the waiting threads will get the mutex and do sometghing useful with qi, without the risk that a third thread will intervene. |
"Hans Bos" <hans.bos@xelion.nl>: Mar 22 04:51PM +0100 "Fred.Zwarts" <F.Zwarts@KVI.nl> wrote in message news:ncrogv$4qi$1@gioia.aioe.org... >> } >> cond.notify_one(); >>} ... > immediately when it unlocks the mutex, one of the waiting threads will get > the mutex and do sometghing useful with qi, without the risk that a third > thread will intervene. The first method has the same problem. Waking a thread with notify_xxx() and aquiring the mutex is not an atomic operation. It is also possible that another thread is waiting for the mutex before notify_one is called. So there is no guarantee that the condition still holds. In http://en.cppreference.com/w/cpp/thread/condition_variable/notify_one the advice is to call the notify_one() without the lock. Regards, Hans. |
SG <s.gesemann@gmail.com>: Mar 22 08:59AM -0700 On Tuesday, March 22, 2016 at 4:32:00 PM UTC+1, F.Zwarts wrote: > In the first method, notif_one is called with the mutex locked, so > immediately when it unlocks the mutex, one of the waiting threads will get > the mutex Is that so? I'm not sure. Suppose there is one blocked consumer thread because the queue is empty. Then, the producer enters the critical section to push an item onto the queue. Then, a second consumer that wasn't blocked tries to enter the critical section. The producer invokes not_empty_condition.notify_one() to wake up a potentially blocked consumer and then unlocks the mutex. Is it guaranteed that the previously blocked consumer thread will be the first to lock the mutex or could the 2nd consumer thread win the race? I was about to write a response similar to yours and that if the notification is kept inside the critical section it should be fine to replace the consumer's while loop std::unique_lock<std::mutex> lck { mut }; while (qi.empty()) { not_empty_condition.wait(lck); } assert(!qi.empty()); // Obviously! to a simple if: std::unique_lock<std::mutex> lck { mut }; if (qi.empty()) { not_empty_condition.wait(lck); } assert(!qi.empty()); // True?! But I'm not so sure about that anymore. Even if the notification is done while the mutex was locked, another consumer could still win the race to lock the mutex and "steal" the item off the queue, couldn't it? I'd recommend to stick with a while loop to be on the safe side (protecting yourself from spurious awakenings). And once you use while loops or the equivalent std::unique_lock<std::mutex> lck { mut }; not_empty_condition.wait(lck, [&]{ return !qi.empty(); }); assert(!qi.empty()); // Obviously you could just as well do the notification outside of the critical section. Whether that makes a difference, I don't know. Cheers! SG |
"Chris M. Thomasson" <nospam@nospam.nospam>: Mar 22 01:16PM -0700 > "Shiyao Ma" wrote in message > news:84adbe2a-758f-4693-8142-c1b1c44ee808@googlegroups.com... [...] Signaling/broadcasting the condvar while the mutex is not held is fine: It can be more efficient. However, on systems that have wait morphing, signaling/broadcasting while the mutex is held should not be less efficient. |
"Chris M. Thomasson" <nospam@nospam.nospam>: Mar 22 01:19PM -0700 > news:ncs985$13lk$1@gioia.aioe.org... >> "Shiyao Ma" wrote in message >> news:84adbe2a-758f-4693-8142-c1b1c44ee808@googlegroups.com... [...] > However, on systems that have wait morphing, > signaling/broadcasting while the mutex is held > should not be less efficient. FWIW, I recommend the excellent book: https://books.google.com/books?id=_xvnuFzo7q0C&pg=PA82&lpg=PA82#v=onepage&q&f=false (linked to a relevant section) |
Jerry Stuckle <jstucklex@attglobal.net>: Mar 21 09:08PM -0400 On 3/21/2016 4:42 PM, Mr Flibble wrote: > Yes it does. > Go read. > /Flibble Learn to read, troll. You've shown repeatedly in this newsgroup by many people just how wrong you are - on so many different subjects. Please feel free to continue to make a fool of yourself. You'll be doing it without me. -- ================== Remove the "x" from my email address Jerry Stuckle jstucklex@attglobal.net ================== |
"Öö Tiib" <ootiib@hot.ee>: Mar 22 12:40AM -0700 On Monday, 21 March 2016 20:51:28 UTC+2, Jens Kallup wrote: > date - a lazy 37 years old non-profit programmer. > More like a Hobbit. > I don't want to initial a flamewar, sorry. You did not initiate flame war. Some typical communication patterns here. > When you spoke over collections - do you mean > containers? vectors? The "collection" is simply OOP term about one-to-many relation from viewpoint of that one. May be even raw array in C++. > Should I use -std-c++11 ? 14? > Is Linux gcc 4.9 to old? 4.9 is Ok for C++11, take newer compiler if you want C++14, C++1y may also be worth trying but it is likely something that C++17 actually won't never be. |
Daniel <danielaparker@gmail.com>: Mar 22 09:58AM -0700 On Monday, March 21, 2016 at 3:47:53 PM UTC-4, Jerry Stuckle wrote: > >> class Square changes the behavior of the Rectangle class. > > Shall we play spot the logical fallacy? > No fallacy - excerpted from real code I've used over the years. The square-rectangle issue has been debated ad nauseam. Uncle Bob" agrees with Mr Flibble :-) More generally, a quick check with google suggests that so do most participants. Most participants find it unsatisfactory that sub-classing Rectangle forces Square to have two attributes when it needs one. And most participants find it unsatisfactory if Square has to violate a Rectangle contract to allow independent setting of width and height. The reason it's debated rather than resolved once-for-all is that, Cardelli notwithstanding, OO is an ad hoc subject, it's not based on theory. OO has it's little principles, such as LSP, but they only go so far. From the point of view of a class designer, nothing is actually gained from sub-classing Square from Rectangle. If there's a need for it, it's always possible to have an abstract base class for both, that defines common behaviour. Daniel |
Jerry Stuckle <jstucklex@attglobal.net>: Mar 22 01:09PM -0400 On 3/22/2016 12:58 PM, Daniel wrote: >>> Shall we play spot the logical fallacy? >> No fallacy - excerpted from real code I've used over the years. > The square-rectangle issue has been debated ad nauseam. Uncle Bob" agrees with Mr Flibble :-) More generally, a quick check with google suggests that so do most participants. Most participants find it unsatisfactory that sub-classing Rectangle forces Square to have two attributes when it needs one. And most participants find it unsatisfactory if Square has to violate a Rectangle contract to allow independent setting of width and height. And a lot of people disagree with Mr. Flibble. :) And Google is hardly a reliable resource; many experts in the field don't bother posting in forums and newsgroups because they rapidly get tired of the arguments from know-it-alls. But I'm not going to continue the argument here. There are too many know-it-alls. > The reason it's debated rather than resolved once-for-all is that, Cardelli notwithstanding, OO is an ad hoc subject, it's not based on theory. OO has it's little principles, such as LSP, but they only go so far. No, OO is not an ad hoc subject. But it does not have strict rules, either. It is based on theory and has principles such as encapsulation, inheritance, etc. But it is not tightly standardized like programming languages. > From the point of view of a class designer, nothing is actually gained from sub-classing Square from Rectangle. If there's a need for it, it's always possible to have an abstract base class for both, that defines common behaviour. That also is debatable. I have done it with great success when I've had to deal with GUIs. There can be a significant amount of code involved, and only one small piece (the height/width) is different between the two. -- ================== Remove the "x" from my email address Jerry Stuckle jstucklex@attglobal.net ================== |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Mar 22 05:46PM On 22/03/2016 01:08, Jerry Stuckle wrote: > people just how wrong you are - on so many different subjects. > Please feel free to continue to make a fool of yourself. You'll be > doing it without me. I also suggest you read about "psychological projection" because you appear to be suffering from it. /Flibble |
Wouter van Ooijen <wouter@voti.nl>: Mar 22 06:51PM +0100 Op 22-Mar-16 om 6:09 PM schreef Jerry Stuckle: > That also is debatable. I have done it with great success when I've had > to deal with GUIs. There can be a significant amount of code involved, > and only one small piece (the height/width) is different between the two. That smells of implementation sharing, which is commonly recognized as a bad reason to use (public) inheritance. Wouter |
legalize+jeeves@mail.xmission.com (Richard): Mar 22 05:58PM [Please do not mail me a copy of your followup] Jens Kallup <jkallup@web.de> spake the secret code > Properties > - Color > - Brush... What you want is composition, not inheritance. You want a 'has-a' relationship, not an 'is-a' relationship. A property is *not* a circle. A property is *not* a rectangle. A rectangle *has* properties. A circle *has* properties. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Computer Graphics Museum <http://computergraphicsmuseum.org> The Terminals Wiki <http://terminals.classiccmp.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
Jerry Stuckle <jstucklex@attglobal.net>: Mar 22 02:04PM -0400 On 3/22/2016 1:46 PM, Mr Flibble wrote: > I also suggest you read about "psychological projection" because you > appear to be suffering from it. > /Flibble Yes, you really do. Because now you're an expert in psychology, also. ROFLMAO! -- ================== Remove the "x" from my email address Jerry Stuckle jstucklex@attglobal.net ================== |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Mar 22 06:08PM On 22/03/2016 17:58, Richard wrote: > A property is *not* a rectangle. > A rectangle *has* properties. > A circle *has* properties. It makes sense for properties such as Color and Brush to be part of the Shape base class as presumably all Shapes have these properties. There is a fundamental rule in OOA/D: prefer composition to inheritance. /Flibble |
Jerry Stuckle <jstucklex@attglobal.net>: Mar 22 02:09PM -0400 On 3/22/2016 1:51 PM, Wouter van Ooijen wrote: > That smells of implementation sharing, which is commonly recognized as a > bad reason to use (public) inheritance. > Wouter Not at all. -- ================== Remove the "x" from my email address Jerry Stuckle jstucklex@attglobal.net ================== |
Jerry Stuckle <jstucklex@attglobal.net>: Mar 22 02:25PM -0400 On 3/22/2016 2:08 PM, Mr Flibble wrote: > Shape base class as presumably all Shapes have these properties. > There is a fundamental rule in OOA/D: prefer composition to inheritance. > /Flibble Incorrect. There is a fundamental rule in OOA/D. Use inheritance where applicable, and composition where applicable. -- ================== Remove the "x" from my email address Jerry Stuckle jstucklex@attglobal.net ================== |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Mar 22 06:38PM On 22/03/2016 18:25, Jerry Stuckle wrote: >> /Flibble > Incorrect. There is a fundamental rule in OOA/D. Use inheritance where > applicable, and composition where applicable. Of course you use things where applicable however if you can solve a problem with either inheritance or composition then prefer composition. So we can currently conclude three things about Jerry Stuckle: 1) He is a troll; 2) He psychologically projects; 3) He is fractally wrong about most things C++ related. /Flibble |
Jerry Stuckle <jstucklex@attglobal.net>: Mar 22 03:56PM -0400 On 3/22/2016 2:38 PM, Mr Flibble wrote: >> applicable, and composition where applicable. > Of course you use things where applicable however if you can solve a > problem with either inheritance or composition then prefer composition. Incorrect. They are two different concepts, with two different usages. You use the one applicable for the situation. There is no "prefer" one over the other. > 2) He psychologically projects; > 3) He is fractally wrong about most things C++ related. > /Flibble And we know Mr. Flibble is a troll and a psychology expert. As well as ignorant as to basic OOAD concepts. -- ================== Remove the "x" from my email address Jerry Stuckle jstucklex@attglobal.net ================== |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Mar 22 08:07PM On 22/03/2016 19:56, Jerry Stuckle wrote: > Incorrect. They are two different concepts, with two different usages. > You use the one applicable for the situation. There is no "prefer" one > over the other. Your fractal wrongness shows no bounds but that is to be expected as that is the nature of fractal wrongness. /Flibble |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Mar 22 08:19PM On 22/03/2016 19:56, Jerry Stuckle wrote: > Incorrect. They are two different concepts, with two different usages. > You use the one applicable for the situation. There is no "prefer" one > over the other. Incorrect am I? "Composition over inheritance (or Composite Reuse Principle) in object-oriented programming is the principle that classes should achieve polymorphic behavior and code reuse by their composition (by containing instances of other classes that implement the desired functionality) rather than inheritance from a base or parent class.[2] This is an often-stated principle of OOP, such as in the influential Design Patterns: "Favor 'object composition' over 'class inheritance'."[3]" https://en.wikipedia.org/wiki/Composition_over_inheritance Now do what I suggested earlier: read a book and actually learn something. /Flibble |
Robert Wessel <robertwessel2@yahoo.com>: Mar 22 12:15AM -0500 On Mon, 21 Mar 2016 12:38:50 -0400 (EDT), bitrex > synthesis.) So 1 LSB maybe? There will be linear interpolation > happening as well so it might be good to store the derivative as > well. I'm not quite sure what you mean by one LSB, but if you meant one ULP (unit in last place) of a float, you'd be OK so long as you did the computation in a double. In you're converting to an int, you should be OK doing the initial calculation with doubles as well. My error estimate was that you'd be looking as something like 200 ULPs worst case (IOW, of a ~53 bit double, about 45 bits would be correct). If you mean to one ULP of a *double*, life gets much more difficult. >Input will actually be floats, with a domain between 0 and 1.0 at > 256 steps. The result will then be shifted and cast to a unit 16 > full with fractional representaton and stored. And you're trying to precompute those ~257 values? Something like this? #include <iostream> #define LIMIT 1000000. constexpr double zexp_w(double x, double x2, double d, double d2) { return ((x2/d2)<(1/LIMIT)) ? 0 : (x2/d2 + zexp_w(x, x*x2, d+1, d2*d)); } constexpr double zexp(double x) { return x<0 ? 1/zexp_w(-x, 1, 1, 1) : zexp_w(x, 1, 1, 1); } inline void test(double x) { double t; t=zexp(x); std::cout << "e**" << x << " = " << t << std::endl; } #define MAGIC_NUM 6.28 constexpr float ff(double x) { return MAGIC_NUM*(1-zexp(-3*(x/256))); } float a[257] = { ff(0), ff(1), ff(2), ff(3), ff(4), ff(5), ff(6), ff(7), ff(8), ff(9), ff(10), ff(11), ff(12), ff(13), ff(14), ff(15), ff(16), ff(17), ff(18), ff(19), ff(20), ff(21), ff(22), ff(23), ff(24), ff(25), ff(26), ff(27), ff(28), ff(29), ff(30), ff(31), ff(32), ff(33), ff(34), ff(35), ff(36), ff(37), ff(38), ff(39), ff(40), ff(41), ff(42), ff(43), ff(44), ff(45), ff(46), ff(47), ff(48), ff(49), ff(50), ff(51), ff(52), ff(53), ff(54), ff(55), ff(56), ff(57), ff(58), ff(59), ff(60), ff(61), ff(62), ff(63), ff(64), ff(65), ff(66), ff(67), ff(68), ff(69), ff(70), ff(71), ff(72), ff(73), ff(74), ff(75), ff(76), ff(77), ff(78), ff(79), ff(80), ff(81), ff(82), ff(83), ff(84), ff(85), ff(86), ff(87), ff(88), ff(89), ff(90), ff(91), ff(92), ff(93), ff(94), ff(95), ff(96), ff(97), ff(98), ff(99), ff(100),ff(101),ff(102),ff(103),ff(104),ff(105),ff(106),ff(107),ff(108),ff(109), ff(110),ff(111),ff(112),ff(113),ff(114),ff(115),ff(116),ff(117),ff(118),ff(119), ff(120),ff(121),ff(122),ff(123),ff(124),ff(125),ff(126),ff(127),ff(128),ff(129), ff(130),ff(131),ff(132),ff(133),ff(134),ff(135),ff(136),ff(137),ff(138),ff(139), ff(140),ff(141),ff(142),ff(143),ff(144),ff(145),ff(146),ff(147),ff(148),ff(149), ff(150),ff(151),ff(152),ff(153),ff(154),ff(155),ff(156),ff(157),ff(158),ff(159), ff(160),ff(161),ff(162),ff(163),ff(164),ff(165),ff(166),ff(167),ff(168),ff(169), ff(170),ff(171),ff(172),ff(173),ff(174),ff(175),ff(176),ff(177),ff(178),ff(179), ff(180),ff(181),ff(182),ff(183),ff(184),ff(185),ff(186),ff(187),ff(188),ff(189), ff(190),ff(191),ff(192),ff(193),ff(194),ff(195),ff(196),ff(197),ff(198),ff(199), ff(200),ff(201),ff(202),ff(203),ff(204),ff(205),ff(206),ff(207),ff(208),ff(209), ff(210),ff(211),ff(212),ff(213),ff(214),ff(215),ff(216),ff(217),ff(218),ff(219), ff(220),ff(221),ff(222),ff(223),ff(224),ff(225),ff(226),ff(227),ff(228),ff(229), ff(230),ff(231),ff(232),ff(233),ff(234),ff(235),ff(236),ff(237),ff(238),ff(239), ff(240),ff(241),ff(242),ff(243),ff(244),ff(245),ff(246),ff(247),ff(248),ff(249), ff(250),ff(251),ff(252),ff(253),ff(254),ff(255),ff(256) }; int main(void) { int i; test(0); test(1); test(1.5); test(2); test(3.14); test(42); test(-1); test(-3.14); test(19.4); for (i=0; i<257; i++) std::cout << MAGIC_NUM << "*(1-e**(" << (-3*(i/256.)) << ") = " << a[i] << std::endl; } (Again, you'll need to generate LIMIT better.) Output: e**0 = 1 e**1 = 2.71828 e**1.5 = 4.48169 e**2 = 7.38906 e**3.14 = 23.1039 e**42 = 1.73927e+18 e**-1 = 0.367879 e**-3.14 = 0.0432828 e**19.4 = 2.66264e+08 6.28*(1-e**(-0) = 0 6.28*(1-e**(-0.0117188) = 0.0731626 6.28*(1-e**(-0.0234375) = 0.145476 6.28*(1-e**(-0.0351563) = 0.216945 6.28*(1-e**(-0.046875) = 0.287581 6.28*(1-e**(-0.0585938) = 0.357393 6.28*(1-e**(-0.0703125) = 0.426396 6.28*(1-e**(-0.0820313) = 0.494593 6.28*(1-e**(-0.09375) = 0.561995 6.28*(1-e**(-0.105469) = 0.628611 6.28*(1-e**(-0.117188) = 0.694451 ... 6.28*(1-e**(-2.87109) = 5.92432 6.28*(1-e**(-2.88281) = 5.92846 6.28*(1-e**(-2.89453) = 5.93256 6.28*(1-e**(-2.90625) = 5.93661 6.28*(1-e**(-2.91797) = 5.94061 6.28*(1-e**(-2.92969) = 5.94456 6.28*(1-e**(-2.94141) = 5.94847 6.28*(1-e**(-2.95313) = 5.95233 6.28*(1-e**(-2.96484) = 5.95615 6.28*(1-e**(-2.97656) = 5.95992 6.28*(1-e**(-2.98828) = 5.96365 6.28*(1-e**(-3) = 5.96734 |
bitrex <bitrex@de.lete.earthlink.net>: Mar 22 10:47AM -0400 On 03/22/2016 01:15 AM, Robert Wessel wrote: > estimate was that you'd be looking as something like 200 ULPs worst > case (IOW, of a ~53 bit double, about 45 bits would be correct). > If you mean to one ULP of a *double*, life gets much more difficult. Yes, I believe that's what I meant, sorry I wasn't more clear. My main gig is electronics/hardware, I'm still learning to code (but hopefully getting better all the time.) I don't believe I have the "double" type available for this processor/codebase, everything I've seen in the libraries that I'm working with uses single-precision "float." > << a[i] << std::endl; > } > (Again, you'll need to generate LIMIT better.) Yeah! That's the ticket. |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment