- Tricky bug - 21 Updates
- Onwards and upwards - 2 Updates
- "Is C++ type-safe? (There's two right answers)" by davmac - 2 Updates
Melzzzzz <Melzzzzz@zzzzz.com>: Dec 15 12:36AM > Interestingly this doesn't happen if I don't compile the code as debug > -code. So the compiler indirectly gives me a hint here for a possible > bug. Joinining in destructor was always no no if Java model is used. Not once I saw pworblems with this in RL. -- current job title: senior software engineer skills: c++,c,rust,go,nim,haskell... press any key to continue or any other to quit... U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec Svi smo svedoci - oko 3 godine intenzivne propagande je dovoljno da jedan narod poludi -- Zli Zec Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi bili naoruzani. -- Mladen Gogala |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Dec 15 01:00AM On Mon, 14 Dec 2020 15:17:55 -0800 > there, and operate on the object before "some more stuff..." had a > chance to run, or right in the middle of it. I have seen code like this > in the past. Then you have incorrect synchronization. I have seen lots of defective code arising from incorrect synchronization, but in your example that has nothing to do with whether the code happens to be running in a constructor or not; it would equally be a problem if any incorrectly synchronized code in derived() were instead contained in an ordinary member function which started a thread. However, there _is_ a problem with the constructor, which is that it calls thread_base::create(), which via thread_base::raw_thread_entry() calls enter() which is a virtual function. |
red floyd <no.spam.here@its.invalid>: Dec 14 08:57PM -0800 On 12/13/2020 1:39 AM, Bonita Montero wrote: > Interestingly this doesn't happen if I don't compile the code as debug > -code. So the compiler indirectly gives me a hint here for a possible > bug. Even if you declare it pure virtual, you still need to provide an implementation for this very scenario. e.g: class Bonita { virtual ~Bonita() = 0; // or is it nullptr here? }; Bonita::~Bonita() { } |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Dec 14 09:53PM -0800 On 12/14/2020 5:00 PM, Chris Vine wrote: > with the constructor, which is that it calls thread_base::create(), > which via thread_base::raw_thread_entry() calls enter() which is a > virtual function. Yeah. your right. I have seen a lot of broken code through the years that has this race condition, to the point where I thought it was a common mistake. Would cringe every time I would see a thread base class. |
Juha Nieminen <nospam@thanks.invalid>: Dec 15 07:11AM > std::shared_ptr then it means its destructor has not yet started > (neither in this nor in another thread), so there is no danger to call a > pure virtual method. You are saying that "if you call the member function from anywhere else than the destructor, it will work fine". I still don't see how std::shared_ptr enters the picture in this. |
Juha Nieminen <nospam@thanks.invalid>: Dec 15 07:13AM > Here's the current state of my thread-pool-class: If you want people to help you with a programming problem, you should make an absolutely minimal piece of code that reproduces the problem, rather than expect people to wade through 400+ lines of cryptic code for you. |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Dec 14 11:22PM -0800 On 12/14/2020 5:45 AM, Bonita Montero wrote: >> } > Otherwise the threads will begin their waiting-period only > after they've processed a queue-entity. This has been tested? |
Bonita Montero <Bonita.Montero@gmail.com>: Dec 15 09:05AM +0100 > make an absolutely minimal piece of code that reproduces the problem, > rather than expect people to wade through 400+ lines of cryptic code > for you. My code is not cryptic. The parts that are not easy to understand are documented. |
Bonita Montero <Bonita.Montero@gmail.com>: Dec 15 09:11AM +0100 >> Otherwise the threads will begin their waiting-period only >> after they've processed a queue-entity. > This has been tested? It doesn't need to be tested since it's trivial. The non-trivial parts are tested. |
Bonita Montero <Bonita.Montero@gmail.com>: Dec 15 09:13AM +0100 >>> Try to emulate in Relacy. >> Not necessary, it's already tested. > Well, it does not hurt to emulate it in a race detector, just for fun? That's not necessary. I've used it in a program with tousands of queue-items and with as much threads as there are hw-threads in my computer (16). |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Dec 15 12:21AM -0800 On 12/15/2020 12:13 AM, Bonita Montero wrote: > That's not necessary. > I've used it in a program with tousands of queue-items and with > as much threads as there are hw-threads in my computer (16). Well, that's not good enough. Sorry. |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Dec 15 12:23AM -0800 On 12/15/2020 12:11 AM, Bonita Montero wrote: >>> after they've processed a queue-entity. >> This has been tested? > It doesn't need to be tested since it's trivial. Well, you did make a "correction", right? You snipped it. Btw, can you please use proper quoting? > The non-trivial parts are tested. How did you test them? |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Dec 15 12:57AM -0800 On 12/13/2020 9:55 AM, Bonita Montero wrote: > Here's the current state of my thread-pool-class: [...] > std::chrono::milliseconds m_timeout; > unsigned m_stop; > unsigned m_nThreads; [...] > { > // one less thread > --m_nThreads; [...] Is m_nThreads allowed to be accessed by multiple threads? |
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Dec 15 01:02AM -0800 On 12/13/2020 9:55 AM, Bonita Montero wrote: > Here's the current state of my thread-pool-class: > // debug_exceptions.h [...] > lock.unlock(); > thread( threadProxy, this ).detach(); > } [...] Are you creating a new thread per-task? |
Paavo Helde <myfirstname@osa.pri.ee>: Dec 15 11:17AM +0200 15.12.2020 09:11 Juha Nieminen kirjutas: > You are saying that "if you call the member function from anywhere else than > the destructor, it will work fine". I still don't see how std::shared_ptr > enters the picture in this. This thread is about calling member functions of an object from another thread while the destructor of the object has already started in the first thread. It's very simple. For avoiding to call a member function from another thread while the destructor of the object has started in the first thread, one needs synchronization. std::shared_ptr is designed to provide that synchronization, and it's in the standard, so it ought to be the preferred method to use. One can use other ways of synchronization, but that would be more complicated and more error-prone (as demonstrated by the first post in this thread - it had synchronization, but in the wrong place). |
"Fred. Zwarts" <F.Zwarts@KVI.nl>: Dec 15 10:58AM +0100 Op 15.dec..2020 om 10:17 schreef Paavo Helde: > One can use other ways of synchronization, but that would be more > complicated and more error-prone (as demonstrated by the first post in > this thread - it had synchronization, but in the wrong place). I understand that shared_ptr can be a good synchronization method, but shared_ptr uses a delete on the pointer when the last shared_ptr is destructed. So, your premise is that a delete can be done, i.e. that the class was created dynamically. Not all classes used by threads are created dynamically, so other synchronization methods are sometimes preferable. |
Bonita Montero <Bonita.Montero@gmail.com>: Dec 15 11:22AM +0100 >> I've used it in a program with tousands of queue-items and with >> as much threads as there are hw-threads in my computer (16). > Well, that's not good enough. Sorry. That's good enough because the synchronization-parts are trivial. |
Bonita Montero <Bonita.Montero@gmail.com>: Dec 15 11:23AM +0100 > Is m_nThreads allowed to be accessed by multiple threads? Yes, but only if the mutex is locked. Sorry, but you seem to be too stupid to read < 250 lines of trivial code. |
Bonita Montero <Bonita.Montero@gmail.com>: Dec 15 11:25AM +0100 Am 15.12.2020 um 10:02 schrieb Chris M. Thomasson: >> } > [...] > Are you creating a new thread per-task? Look here: // we've less threads than allowed and those which are not running // are gonna occupied by the thread-queue items ? if( m_nThreads < m_maxThreads && m_nThreads - m_nThreadsRunning <= m_taskQueue.size() ) The code is documented and you can't read it. Again: this checks if there are less threads than m_maxThreads and the threads not currently active might be all occupied by not accepted queue -items. |
Bonita Montero <Bonita.Montero@gmail.com>: Dec 15 11:39AM +0100 > virtual ~Bonita() = 0; // or is it nullptr here? > }; > Bonita::~Bonita() { } That's true for a pure-virtual destructor because it is called for every object which is destructed. But that's not true for objects whose pure virtual methods aren't called. |
Paavo Helde <myfirstname@osa.pri.ee>: Dec 15 01:56PM +0200 15.12.2020 11:58 Fred. Zwarts kirjutas: > class was created dynamically. Not all classes used by threads are > created dynamically, so other synchronization methods are sometimes > preferable. Right, and these methods are more complicated and more error-prone. Let's see in which ways I would have a thread-shared object which is not allocated dynamically, and there is a danger that another thread might call its member functions while its destructor has started. 1. It's a global static. When its destructor is started, it means that the program is about to terminate. Before terminating all other threads should be already joined, so the situation described by OP cannot happen at all (or in other words, thread joining provides the needed synchronization here). 2. It's a local variable in a stack frame. Passing a pointer of a local stack variable to another thread is pretty fragile, needs complicated synchronization and is error-prone. I hope you do not argue with that. In particular, having the synchronization in a base class destructor cannot work, but nevertheless this approach seems to be invariably reinvented all the time, by some reason. 3. It's a member variable in another larger object which is allocated dynamically and shared between the threads. In that case the larger object should be accessed via a shared_ptr, and the whole issue does not appear. |
Brian Wood <woodbrian77@gmail.com>: Dec 14 10:41PM -0800 On Sunday, December 13, 2020 at 6:35:59 AM UTC-6, Chris Vine wrote: > Out of interest, if you are willing to share the information, what is it > that you or your company produces which is "doing better today than > ever"? The software is more mature and versatile than a year ago. SaaS is doing well. As far as I can tell I'm sitting on a gold mine. > this newsgroup.) I have occasionally wondered how your business manages > to keep going. If you do have customers for your code generation tool > then I am please to hear it. I'm still looking for some initial external users. Perhaps I should increase the referral bonus that I offer for help finding someone willing to use my software. > interested in your religious views: I have a general interest in what > makes a business successful and I am talking about dollars, cents and > commercial product here. "In G-d we trust" has been the national motto of the US for many years. That trust extends to how you build and run a business. I don't know if you're prying, but am thinking about Samson and Delilah. She fooled Samson into trusting her and giving her information that she used against him. Upthread I wrote about "In a place where there are no men, strive to be a man!" Samson was a strong guy physically, but didn't strive hard enough to be a man in other ways and he fell victim to the devious Delilah. |
David Brown <david.brown@hesbynett.no>: Dec 15 11:48AM +0100 On 15/12/2020 07:41, Brian Wood wrote: > The software is more mature and versatile than a year ago. > SaaS is doing well. As far as I can tell I'm sitting on a > gold mine. No one has ever had success by /sitting/ on a gold mine. The mine has to be used - it has to be /producing/ gold. And it is only worth something if other people think it is worth something. /I/ don't know enough about your software or services to know what they might be worth, but surely the popularity of it, or lack thereof, is a good indication. > I'm still looking for some initial external users. Perhaps I should > increase the referral bonus that I offer for help finding someone > willing to use my software. "The beatings will continue until morale improves" ? "The definition of insanity is doing the same thing over and over again and expecting different results." (Regularly but incorrectly attributed to Einstein.) If there has been no interest with the offer you have already provided, why would you think that increasing it would help? If you have been at this for 10 years, and have /no/ users, then it is surely time to change tactics. For example, you could stop telling people your software is so useless that you will pay people to use it, and instead start charging for it. People will then see it might be worth something. > "In G-d we trust" has been the national motto of the US > for many years. That trust extends to how you build > and run a business. Some people can't properly separate their own personal beliefs from their business or their software development. Most people can. Those that can keep them separate are not going to be interested in software or a company that keeps mixing in religion. And those that /are/ particularly religious themselves, will be quite happy to use "non-religious" software. So basically, all you are doing by mixing religion in your business is alienating some 90%+ of potential users. The same goes for political views and anything else that is /personal/, not related to business or software. > men, strive to be a man!" Samson was a strong guy > physically, but didn't strive hard enough to be a man > in other ways and he fell victim to the devious Delilah. Please stop comparing yourself to characters from the Bible. It doesn't help your case. If you want people to use your software, then you really have to think about how you appear to people. Alternatively, if you want to continue to promote yourself as some sort of modern Biblical Patriarch and preach your religion, then consider changing career - get a TV channel, start a church, or write a book. |
Lynn McGuire <lynnmcguire5@gmail.com>: Dec 14 06:38PM -0600 "Is C++ type-safe? (There's two right answers)" by davmac https://davmac.wordpress.com/2020/12/13/is-c-type-safe-theres-two-right-answers/ Yup, he is right. And that is why C++ works. And we have wayyyyy too many type casts in our software. Lynn |
Melzzzzz <Melzzzzz@zzzzz.com>: Dec 15 01:05AM > https://davmac.wordpress.com/2020/12/13/is-c-type-safe-theres-two-right-answers/ > Yup, he is right. And that is why C++ works. And we have wayyyyy too > many type casts in our software. Language without undefined behavior would be useless for low level programming. Speaking of safety Rust vs C++ is it better not to have pointer arithmetic and do that by converting pointer to int and back and C++ model in which you just add value to pointer? -- current job title: senior software engineer skills: c++,c,rust,go,nim,haskell... press any key to continue or any other to quit... U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec Svi smo svedoci - oko 3 godine intenzivne propagande je dovoljno da jedan narod poludi -- Zli Zec Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi bili naoruzani. -- Mladen Gogala |
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