MESSAGE
DATE | 2016-12-22 |
FROM | ruben safir
|
SUBJECT | Subject: [Learn] Fwd: Re: thread concurancy
|
From learn-bounces-at-nylxs.com Thu Dec 22 11:00:01 2016 Return-Path: X-Original-To: archive-at-mrbrklyn.com Delivered-To: archive-at-mrbrklyn.com Received: from www.mrbrklyn.com (www.mrbrklyn.com [96.57.23.82]) by mrbrklyn.com (Postfix) with ESMTP id 38781161317; Thu, 22 Dec 2016 11:00:01 -0500 (EST) X-Original-To: learn-at-nylxs.com Delivered-To: learn-at-nylxs.com Received: from [10.0.0.62] (flatbush.mrbrklyn.com [10.0.0.62]) by mrbrklyn.com (Postfix) with ESMTP id AD13A161311; Thu, 22 Dec 2016 10:59:59 -0500 (EST) References: To: learn-at-nylxs.com From: ruben safir X-Forwarded-Message-Id: Message-ID: Date: Thu, 22 Dec 2016 10:59:59 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.5.1 MIME-Version: 1.0 In-Reply-To: Subject: [Learn] Fwd: Re: thread concurancy X-BeenThere: learn-at-nylxs.com X-Mailman-Version: 2.1.17 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: learn-bounces-at-nylxs.com Sender: "Learn"
-------- Forwarded Message -------- Subject: Re: thread concurancy Date: Thu, 22 Dec 2016 12:32:15 +0200 From: Paavo Helde Newsgroups: comp.lang.c++ References:
On 22.12.2016 6:48, ruben safir wrote: > > How is this fix ;)
Yes, this makes a bit more sense, at least the mutex is really used for mutual exclusion. A couple of remarks:
The functions get_canvas_index() and get_source_index() are lacking the mutex lock. Any access to data which is concurrently modified needs a mutex lock.
The function get_canvas() returns a pointer to the shared array without any synchronization. This means race conditions. Instead, it should wait on a std::condition_variable until all threads have fulfilled the task; upon completion, each thread should increment a counter of completed tasks under another mutex lock and notify the condition variable. (In this toy example this waiting could be replaced by just joining all the threads, but in real life you typically don't want to terminate your service threads after each task.)
The mutex is defined in another place (a global!) than the protected data. This is insane. The mutex should be together with the protected data, preferably in its own section of private variables, clearly documented:
private: // data members protected by medco std::mutex medco; char * canvas_index; char * source_index;
private: // other data // ...
The thread array t is also global, with no need, no protection, etc. As soon as you create another instance of PIC it gets garbled.
HTH Paavo
> > /* > * ===================================================================================== > * > * Filename: test.cpp > * > * Description: Threading Experiment > * > * Version: 1.0 > * Created: 12/18/2016 12:46:51 PM > * Revision: none > * Compiler: gcc > * > * Author: Ruben Safir (mn), ruben-at-mrbrklyn.com > * Company: NYLXS Inc > * > * ===================================================================================== > */ > > #include > #include > #include > std::mutex medco; > std::mutex master; > > namespace testing{ > std::thread t[10]; > class PIC > { > public: > PIC():source_index{&source[0]} > { > canvas_index = canvas; > std::cout << "Testing Source" << std::endl; > for(int i = 0; i<100; i++) > { > std::cout << i << " " << source[i] << std::endl ; > } > > for(int i = 0; i < 10;i++) > { > t[i] = std::thread([this]{ readin(); }); > std::cerr << i << ": Making a thread" << std::endl; > } > }; > > > ~PIC() > { > std::cerr << "In the destructor" << std::endl; > for(int i=0; i<10; i++) > { > t[i].join(); > std::cerr << i << ": Joining a thread" << std::endl; > } > > }; > > void readin() > { > char * loc_canvas_index; > char * loc_source_index; > sync_canvas_and_input(loc_canvas_index, loc_source_index); > > for( int i = 9; i>=0; i-- ) > { > *loc_canvas_index = loc_source_index[i]; > std::cerr << i << ": Copy " << loc_source_index[i] << std::endl; > std::cerr << i << ": Copied to loc_canvas_index " << reinterpret_cast(*loc_canvas_index) << std::endl; > loc_canvas_index++; > } > > }; > void sync_canvas_and_input(char * &loc_canvas_index, char * &loc_source_index ) > { > std::cout << "**LOCKING**" << std::endl; > std::lock_guard turn(medco); > loc_canvas_index = canvas_index; > loc_source_index = source_index; > source_index += 10; > canvas_index += 10; > }; > > char * get_canvas() > { > return canvas; > } > char * get_canvas_index() > { > return canvas_index; > } > char * get_source_index() > { > return source_index; > } > > private: > char * canvas = new char[100]{ > 'z', 'z','z','z','z','z','z','z','z','z', > 'z', 'z','z','z','z','z','z','z','z','z', > 'z', 'z','z','z','z','z','z','z','z','z', > 'z', 'z','z','z','z','z','z','z','z','z', > 'z', 'z','z','z','z','z','z','z','z','z', > 'z', 'z','z','z','z','z','z','z','z','z', > 'z', 'z','z','z','z','z','z','z','z','z', > 'z', 'z','z','z','z','z','z','z','z','z', > 'z', 'z','z','z','z','z','z','z','z','z', > 'z', 'z','z','z','z','z','z','z','z','z' > }; > char * canvas_index; > char source[100] = { > 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', > 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', > 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', > 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', > 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', > 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', > 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', > 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', > 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', > 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' > }; > char * source_index; > }; > }//end namespace > > int main(int argc, char** argv) > { > testing::PIC fido; > for(int i = 0; i<100;i++) > { > std::cout << i << " Canvas Position " << fido.get_canvas()[i] << std::endl; > } > > return 0; > } >
_______________________________________________ Learn mailing list Learn-at-nylxs.com http://lists.mrbrklyn.com/mailman/listinfo/learn
|
|