- C++ condition variable confusion - 10 Updates
- Need help understanding code segment - 3 Updates
- initialization and copying of class array member - 2 Updates
"Chris M. Thomasson" <invalid_chris_thomasson_invalid@invalid.com>: Mar 15 08:20PM -0700 On 3/14/2019 10:12 AM, Bonita Montero wrote: >> thread will arrive at wait() before the main thread has called >> notify_one(). > That's intended and this might result in a spurious wakeup of a thread. Indeed. > I.e. the wakeup might be consumed by another thread. Because of that > the flag is checked in a loop to detect this kind of wakeups. Ditto. |
"Chris M. Thomasson" <invalid_chris_thomasson_invalid@invalid.com>: Mar 15 08:23PM -0700 > hangs and the thread never leaves the wait() called? My understanding is that > wait() should exit immediately upon receiving a notification but this doesn't > happen. [...] A condition needs a predicate. Loop on it while waiting on the condvar. Mutate the predicate under protection of the mutex, signal or broadcast depending on what your state is designed to do. Fwiw, there are some interesting places where one needs to use broadcast instead of signal. A signal can go to any thread. A lot of people over the years really do miss the predicate in the condvar wait. They seem to mistakenly treat like some sort of event. Imvvho, read the following book several times: https://www.amazon.com/Programming-POSIX-Threads-David-Butenhof/dp/0201633922 Then, read it again... ;^) |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Mar 16 01:17PM +0100 On 16.03.2019 04:23, Chris M. Thomasson wrote: > mistakenly treat like some sort of event. > Imvvho, read the following book several times: > https://www.amazon.com/Programming-POSIX-Threads-David-Butenhof/dp/0201633922 I expressed the first program, on page 14 of the 1997 edition, in C++: ----------------------------------------------------------------------------- // A C++ version of "alarm.c" on page 14 of "Programming with Posix threads" 1997. #include <cppx-core/_all_.hpp> // https://github.com/alf-p-steinbach/cppx-core $use_std( streambuf, cin, cout, cerr, endl, istream, string, getline, ws ); $use_namespace_names_in( std, chrono, this_thread ); void clear( istream& stream ) { stream.clear(); stream.sync(); streambuf* p_buf = stream.rdbuf(); while( p_buf->in_avail() > 0 ) { p_buf->sbumpc(); } } auto main() -> int { for( ;; ) { cout << "Alarm> "; int n_seconds; string message; const bool ok_input = (cin >> n_seconds >> ws and getline( cin, message )); if( not ok_input ) { cerr << "Bad command" << endl; clear( cin ); continue; } this_thread::sleep_for( chrono::seconds( n_seconds ) ); cout << "(" << n_seconds << ") " << message << endl; } } ----------------------------------------------------------------------------- Not sure if I'm going on with the idea of expressing all those programs in C++. It may be very slow going. Cheers!, - Alf |
johnbenny@nowhere.co.uk: Mar 16 12:46PM On Fri, 15 Mar 2019 18:36:36 +0000 >which takes a predicate and so avoids the need to code your own while >loop, namely: > void wait(std::unique_lock<std::mutex>& lock, Predicate pred); I know. > while (!pred()) { > wait(lock); > } And that solves what? If its going to spin on a predicate you might just as well write your own flag based spin loop and not bother with condition variables in the first place. |
Bo Persson <bo@bo-persson.se>: Mar 16 02:08PM +0100 > And that solves what? If its going to spin on a predicate you might just as > well write your own flag based spin loop and not bother with condition > variables in the first place. It still waits on the lock, but rechecks the condition when it wakes up. Bo Persson |
Sam <sam@email-scan.com>: Mar 16 09:22AM -0400 > read from it. It stays there until a read occurs so avoiding data loss and > race > conditions. I don't see why the thread notify can't be the same. Should you have to write a long and complicated C++ program to do a particular task, correctly? Why can't you just #include some header file, and have everything happen, by magic! > >times it's been notified. Now, you can feel free to pretend that's how > >threads get notified in your entire application. > Meanwhile with socket & pipe based IPC I can just sit in a select(). No So, go ahead and do it. There is no law that says you can't create a pipe, have one of your threads write to it, and the other one of your threads read from it. > about with control variables and mutexes. When data arrives the function > exits > whether that data was written before it was entered or after. This is how threads, mutexes, and condition variables work. You can either use them correctly, or bitch about them on Usenet to anyone who cares. Your choice. Sometimes life is not fair, and simple things become difficult, or there are complications. Most people learn that by their late teens. Most people also learn that if they find it difficult to turn a screw by hand, they can go and get a tool called a "screwdriver". Similarly, there's a shitload of C++ libraries out there that implement tools to wrap C++ thread primitives into higher-level constructs, that one can use directly. C++ is not a kitchen sink programming language, full of magic buttons one needs to only push, and have everything happen correctly. The C++ library provides basic primitives, and one needs to learn how to use them correctly. C++ never had a reputation for instant gratification, and is the most complex general purpose programming language in use today. Why there are even libraries out there that implement design patterns that force you, by contract, to lock a mutex before being able to access a mutex- protected object, and have the related condition variable notifiable only when holding a lock on the mutex; and basically make it logically impossible to use mutexes and condition variables incorrectly. Isn't modern technology great? |
Paavo Helde <myfirstname@osa.pri.ee>: Mar 16 03:53PM +0200 > And that solves what? If its going to spin on a predicate you might just as > well write your own flag based spin loop and not bother with condition > variables in the first place. You could, but your program would consume 100% CPU with spinning, versus 0% with wait. Why don't you try out different variants by yourself and see how they behave? You are just banging your head against the wall now. |
scott@slp53.sl.home (Scott Lurndal): Mar 16 04:11PM >And that solves what? If its going to spin on a predicate you might just as >well write your own flag based spin loop and not bother with condition >variables in the first place. The difference, of course, is that 'wait' will cause the host operating system schedulerr to schedule something else on that core/hardware thread (or put it in a low-power state during the wait). A spin loop both prevents other processes from getting CPU time as well as burns power. |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Mar 16 08:38PM On Sat, 16 Mar 2019 12:46:24 +0000 (UTC) > And that solves what? If its going to spin on a predicate you might just as > well write your own flag based spin loop and not bother with condition > variables in the first place. You completely misunderstand this I am afraid. First, you need to check when you begin the wait whether the condition is already fulfilled, so you require as a minimum an if statement. That was your original coding mistake. Secondly, in a perfect world, having an if block would be enough, but it is specifically documented by both POSIX and C++11 that a condition variable may spuriously wake up for efficiency of implementation reasons. It happens very rarely, but it can happen. So you use a while loop. The while loop does not imply spinning as you seem to think. |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Mar 16 08:50PM On Sat, 16 Mar 2019 20:38:09 +0000 Chris Vine <chris@cvine--nospam--.freeserve.co.uk> wrote: [snip] > by both POSIX and C++11 that a condition variable may spuriously wake > up for efficiency of implementation reasons. It happens very rarely, > but it can happen. So you use a while loop. Add to this that it is also documented that signalling a condition variable may wake up more than one thread - so you need a while loop for that reason also if more than one thread may be waiting on the variable. (And a broadcast is also obliged to wake up all threads waiting on the condition variable, irrespective of whether the condition is satisfied for all the waiting threads.) |
David Brown <david.brown@hesbynett.no>: Mar 16 01:19PM +0100 On 15/03/2019 16:50, Peabody wrote: > computers, can update firmware with a USB cable and a cheap > USB adapter, or possibly just the cable since the adapter > can be embedded on the project's board as in Arduinos. There is no problem with having Python installed on the user's machines. If they have Linux, they have Python. If they have Windows, you can build an exe file with all the bits of Python that are needed. (That exe file is going to be massively bigger than a C++ sourced exe file - but do you really care about that?) You don't even need to touch a line of Python code normally - the tools already handle many use-cases. <https://pypi.org/project/python-msp430-tools/> There are other ready-made tools and libraries on TI's website (not just the Python ones): <http://www.ti.com/tool/MSPBSL> The point is, don't try to program this stuff yourself unless you really have to. Use existing programs. > installing the adapter's VCP driver if it's not already > included in their OS. I'm just not sure a Python solution > works as well for the general public. The Python solution has been working fine for developers and end-users for long before TI thought it might be an idea to release programs themselves. Don't get me wrong here - the Python tools are not the only way to do this, and Python is not necessarily the best solution for all BSL cases. I simply want you to think more clearly about the situation. Don't think "I know a little bit of C, therefore the C++ code is the way to go". Don't think "I don't know much about Python, I can't use it". Don't think about the limitations you are imagining, but think of a wide variety of possible solutions before deciding. If you end up using the C++ code, do so because you have worked through this and seen C++ as the shortest route to your goals. |
Peabody <waybackNO584SPAM44@yahoo.com>: Mar 16 09:18AM -0500 David Brown says... > normally - the tools already handle many use-cases. > There are other ready-made tools and libraries on TI's > website (not just the Python ones): I've looked through TI's stuff more than once, and there's nothing there that addresses the problem. This comes up repeatedly on the TI forum - Can I flash firmware to an F4xx (or any of the newer parts) using an FT232 USB-to-UART adapter with TI's Windows flashing software? Not an unreasonable question. And the answer from TI is always - No, we don't support that. You'll need to use an MSP-FET [$115] or a "Rocket" [$15]. A generic USB adapter [$1.20] won't work. As I see it, the problem is really very simple. I don't need to write a new program. TI has already written and made available, with source code, software that works perfectly, so long as you use their proprietary and expensive hardware interface. Of course there are other solutions, such as writing your own BSL for the chip. And as you say, a Python solution may exist. But it just seems that the obvious solution is to take TI's source code and make a few minor changes, then recompile, and then it *WILL* work with those adapters. I've already done this for the older parts that use BSLDEMO. It was literally just adding options to invert the polarity of DTR and RTS. But that was a simple program, written in C, and I was able to use LCC-Win32 to compile it with a fairly short learning curve. No BOOST involved. But BSL-Scripter for the newer parts is more difficult. The code changes are not really the problem. I think I now understand the functions that change the state of DTR and RTS, and last night I finished the changes I needed to add the option to generate the hardware invoke pattern. It's just a few lines in four of the 57 source code files. The problem now is in compiling it. Here's what I'm up against: https://github.com/drcrane/bslscripter-windows I read through the README, and I just have no idea what it means. The is not LCC, and I don't do this stuff for a living. I don't have Visual C++, Boost, or any of the other libraries, nor do I have any idea of how all this works. I was hoping the process would be less obscure, but I would spend days, or more likely weeks, learning how all this works - just to get the existing code to compile, and I really don't want to do that just for this, particularly with no prospect of ever needing to use it again. So maybe the guy who did the repo will compile my changes for me, but if not, I will probably drop it. If there's an existing Python solution, people can use that with no input from me. And there's always a chance that TI will do the right thing and make this change themselves, which of course is what really should happen, and which I've asked them to do. |
Louis Krupp <lkrupp@nospam.pssw.com.invalid>: Mar 16 02:10PM -0600 On Sat, 16 Mar 2019 09:18:46 -0500, Peabody >right thing and make this change themselves, which of course >is what really should happen, and which I've asked them to >do. There are TI product forums: https://e2e.ti.com/support/ Maybe someone on one of those has built the tool. Louis |
wyniijj@gmail.com: Mar 15 09:49PM -0700 I'm trying implementing a fixed-size matrix class. But before that, I should implement a fixed size 'vector' class template. From the very begining of the impl., I feel copy ctor and linitializer_list ctor are somewhat inefficient because they use loop instead of direct element-wise copy which I thought might be possible(or not? because C array is not assignable). Do I have to do it this way? template<typename T, size_t N> class Vect { T m_arr[N]; public: Vect() {}; Vect(const Vect& s) { for(size_t i=0; i<N; ++i) { m_arr[i]=s.m_arr[i]; } }; Vect(std::initializer_list<T> s) { T* wptr=m_arr; for(const T* iptr=s.begin(); iptr<s.end(); ++iptr) { *wptr=*iptr; ++wptr; } }; Vect& operator=(const Vect& s) { /*same as ctor */ }; Vect& operator=(std::initializer_list<T> s) { /*same as cotr*/ }; }; E.g. Vect<float,3> arr{1,2,3},arr2(arr); arr={3,4,5}; // assignment has the same efficiency issue arr=arr2; The second problem is when T is integer type or float type, can I use memcpy from the argument s? E.g. Vect(const Vect& s) { memcpy(m_arr,s.m_arr,sizeof(m_arr)); }; Vect(std::initializer_list<T> s) { memcpy(m_arr,s.begin,sizeof(m_arr)); }; |
Juha Nieminen <nospam@thanks.invalid>: Mar 16 05:04PM > because C array is not assignable If you want an assignable C-style static array, use std::array. (It has all the same characteristics as a "raw" array, except that it's directly copyable and assignable.) --- news://freenews.netfront.net/ - complaints: news@netfront.net --- |
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