Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #47488 > unrolled thread
| Started by | Popping mad <rainbow@colition.gov> |
|---|---|
| First post | 2016-12-21 20:48 +0000 |
| Last post | 2016-12-22 11:00 -0500 |
| Articles | 14 — 6 participants |
Back to article view | Back to comp.lang.c++
thread concurancy Popping mad <rainbow@colition.gov> - 2016-12-21 20:48 +0000
Re: thread concurancy Paavo Helde <myfirstname@osa.pri.ee> - 2016-12-21 23:39 +0200
Re: thread concurancy ruben safir <ruben@mrbrklyn.com> - 2016-12-21 23:48 -0500
Re: thread concurancy Paavo Helde <myfirstname@osa.pri.ee> - 2016-12-22 12:32 +0200
Re: thread concurancy ruben safir <ruben@mrbrklyn.com> - 2016-12-22 12:13 -0500
Re: thread concurancy Paavo Helde <myfirstname@osa.pri.ee> - 2016-12-22 20:29 +0200
Re: thread concurancy scott@slp53.sl.home (Scott Lurndal) - 2016-12-23 14:31 +0000
Re: thread concurancy Paavo Helde <myfirstname@osa.pri.ee> - 2016-12-23 20:19 +0200
Re: thread concurancy scott@slp53.sl.home (Scott Lurndal) - 2016-12-23 22:39 +0000
Re: thread concurancy Paavo Helde <myfirstname@osa.pri.ee> - 2016-12-24 01:31 +0200
Re: thread concurancy ruben safir <ruben@mrbrklyn.com> - 2016-12-21 23:49 -0500
Re: thread concurancy "Chris M. Thomasson" <invalid@invalid.invalid> - 2016-12-23 15:19 -0800
Re: thread concurancy Sal LO <gegefffffff@gmail.com> - 2016-12-22 07:04 -0800
Re: thread concurancy ruben safir <ruben@mrbrklyn.com> - 2016-12-22 11:00 -0500
| From | Popping mad <rainbow@colition.gov> |
|---|---|
| Date | 2016-12-21 20:48 +0000 |
| Subject | thread concurancy |
| Message-ID | <o3eprl$1pf$2@reader1.panix.com> |
:(
I don't know. I'm very confused about the behavior of this test program I've been right.
I'm trying to move date by worker threads from one blob of memory to another and the debugger
is saying that the pointers beg and canvas_index is jumping 10 bytes between this two lines
for(int i = 0; i < 10;i++)
{
t[i] = std::thread([this]{ readin(beg, canvas_index); });
and I'm not sure why. I lost the concurrency somewhere, but can't seem to figure out what I did wrong
#include <iostream>
#include <thread>
#include <mutex>
std::mutex medco;
std::mutex master;
namespace testing{
std::thread t[10];
class PIC
{
public:
PIC():beg{&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(beg, canvas_index); });
std::cerr << i << ": Making a thread" << std::endl;
sync_canvas_and_input();
}
};
void sync_canvas_and_input()
{
std::cout << "**LOCKING**" << std::endl;
std::lock_guard<std::mutex> turn(medco);
beg += 10;
canvas_index += 10;
}
~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 * start, char * loc_canvas_index)
{
for( int i = 9; i>=0; i-- )
{
*loc_canvas_index = start[i];
std::cerr << i << ": Copy " << start[i] << std::endl;
std::cerr << i << ": Copied to loc_canvas_index " << reinterpret_cast<char>(*loc_canvas_index) << std::endl;
loc_canvas_index++;
}
[toc] | [next] | [standalone]
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2016-12-21 23:39 +0200 |
| Message-ID | <OfqdnfvRg5oya8fFnZ2dnUU78KHNnZ2d@giganews.com> |
| In reply to | #47488 |
On 21.12.2016 22:48, Popping mad wrote:
> :(
>
> I don't know. I'm very confused about the behavior of this test program I've been right.
> I'm trying to move date by worker threads from one blob of memory to another and the debugger
> is saying that the pointers beg and canvas_index is jumping 10 bytes between this two lines
>
> for(int i = 0; i < 10;i++)
> {
> t[i] = std::thread([this]{ readin(beg, canvas_index); });
>
> and I'm not sure why. I lost the concurrency somewhere, but can't seem to figure out what I did wrong
Who knows. Debuggers sometimes also get confused and display wrong data.
Your example is incomplete (truncated?), cannot be compiled and even the
types of beg and canvas_index are not known. So not much can be said
about the code.
From the visible code I can only infer that you have not understood why
and how to protect data with mutexes (mutex lock is in one thread only,
and the data apparently protected by the lock (beg, canvas_index) is
not even accessed in the other threads.
Also, access to the shared data buffer (canvas) is creating a lot of
false sharing as the slicing size 10 is most probably not divisible by
the cache line size, thus causing potentially significant performance
penalties (probably not important for your toy example, but worth to
mention).
>
> #include <iostream>
> #include <thread>
> #include <mutex>
> std::mutex medco;
> std::mutex master;
>
> namespace testing{
> std::thread t[10];
> class PIC
> {
> public:
> PIC():beg{&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(beg, canvas_index); });
> std::cerr << i << ": Making a thread" << std::endl;
> sync_canvas_and_input();
> }
> };
>
> void sync_canvas_and_input()
> {
> std::cout << "**LOCKING**" << std::endl;
> std::lock_guard<std::mutex> turn(medco);
> beg += 10;
> canvas_index += 10;
> }
>
> ~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 * start, char * loc_canvas_index)
> {
> for( int i = 9; i>=0; i-- )
> {
> *loc_canvas_index = start[i];
> std::cerr << i << ": Copy " << start[i] << std::endl;
> std::cerr << i << ": Copied to loc_canvas_index " << reinterpret_cast<char>(*loc_canvas_index) << std::endl;
> loc_canvas_index++;
> }
>
[toc] | [prev] | [next] | [standalone]
| From | ruben safir <ruben@mrbrklyn.com> |
|---|---|
| Date | 2016-12-21 23:48 -0500 |
| Message-ID | <o3flum$ku0$1@reader1.panix.com> |
| In reply to | #47493 |
How is this fix ;)
/*
* =====================================================================================
*
* 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@mrbrklyn.com
* Company: NYLXS Inc
*
* =====================================================================================
*/
#include <iostream>
#include <thread>
#include <mutex>
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<char>(*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<std::mutex> 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;
}
[toc] | [prev] | [next] | [standalone]
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2016-12-22 12:32 +0200 |
| Message-ID | <zf6dnRCNKN4yNsbFnZ2dnUU78a_NnZ2d@giganews.com> |
| In reply to | #47505 |
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@mrbrklyn.com
> * Company: NYLXS Inc
> *
> * =====================================================================================
> */
>
> #include <iostream>
> #include <thread>
> #include <mutex>
> 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<char>(*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<std::mutex> 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;
> }
>
[toc] | [prev] | [next] | [standalone]
| From | ruben safir <ruben@mrbrklyn.com> |
|---|---|
| Date | 2016-12-22 12:13 -0500 |
| Message-ID | <o3h1je$pd8$1@reader1.panix.com> |
| In reply to | #47509 |
On 12/22/2016 05:32 AM, Paavo Helde wrote: > 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. Wouldn't that cause a deadlock condition?
[toc] | [prev] | [next] | [standalone]
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2016-12-22 20:29 +0200 |
| Message-ID | <U7WdnX_D4IUZhsHFnZ2dnUU78dPNnZ2d@giganews.com> |
| In reply to | #47518 |
On 22.12.2016 19:13, ruben safir wrote: > On 12/22/2016 05:32 AM, Paavo Helde wrote: >> 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. > > > Wouldn't that cause a deadlock condition? Deadlock means that at least 2 threads wait for each other. In your example there is only one function, called in a single thread only, which ever waits for anything (the destructor, in the thread join operations), so there is no possibility of deadlocks. Or alternatively, if you look at the code of sync_canvas_and_input() then you see that when it has locked the mutex it will release it again a microsecond or so later, unconditionally. Mutex locks in get_canvas_index() and get_source_index() are needed so that these functions would not return incompatible or garbage information during this microsecond. This is the whole point of "mutual exclusion".
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2016-12-23 14:31 +0000 |
| Message-ID | <Mya7A.22404$rv4.21954@fx01.iad> |
| In reply to | #47509 |
Paavo Helde <myfirstname@osa.pri.ee> writes: >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. Not necessarily - atomics are a viable alternative.
[toc] | [prev] | [next] | [standalone]
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2016-12-23 20:19 +0200 |
| Message-ID | <p7udnWEM59Eu98DFnZ2dnUU78bHNnZ2d@giganews.com> |
| In reply to | #47544 |
On 23.12.2016 16:31, Scott Lurndal wrote: > Paavo Helde <myfirstname@osa.pri.ee> writes: >> 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. > > Not necessarily - atomics are a viable alternative. Yes, atomics are fine in many situations, but not here, in the OP example. They are updated and read concurrently by the sync_canvas_and_input() function. If it was using 2 atomics instead, then the values returned are not guaranteed to be in sync, which would cause interesting bugs (swapped slices in the result).
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2016-12-23 22:39 +0000 |
| Message-ID | <TIh7A.373814$aJ2.363027@fx38.iad> |
| In reply to | #47553 |
Paavo Helde <myfirstname@osa.pri.ee> writes: >On 23.12.2016 16:31, Scott Lurndal wrote: >> Paavo Helde <myfirstname@osa.pri.ee> writes: >>> Any access to data which is concurrently modified needs a >>> mutex lock. >> >> Not necessarily - atomics are a viable alternative. > >Yes, atomics are fine in many situations, but not here, in the OP You stated, as above, "Any access to data which is concurrently modified needs a mutex lock". To which I replied as shown. I made no claim about the OP's code.
[toc] | [prev] | [next] | [standalone]
| From | Paavo Helde <myfirstname@osa.pri.ee> |
|---|---|
| Date | 2016-12-24 01:31 +0200 |
| Message-ID | <AdmdndX39LUoLsDFnZ2dnUU78a2dnZ2d@giganews.com> |
| In reply to | #47573 |
On 24.12.2016 0:39, Scott Lurndal wrote: > Paavo Helde <myfirstname@osa.pri.ee> writes: >> On 23.12.2016 16:31, Scott Lurndal wrote: >>> Paavo Helde <myfirstname@osa.pri.ee> writes: > >>>> Any access to data which is concurrently modified needs a >>>> mutex lock. >>> >>> Not necessarily - atomics are a viable alternative. >> >> Yes, atomics are fine in many situations, but not here, in the OP > > You stated, as above, "Any access to data which is concurrently > modified needs a mutex lock". To which I replied as shown. I > made no claim about the OP's code. Right, I should have worded my claims more carefully! Merry Christmas! p
[toc] | [prev] | [next] | [standalone]
| From | ruben safir <ruben@mrbrklyn.com> |
|---|---|
| Date | 2016-12-21 23:49 -0500 |
| Message-ID | <o3fm07$ku0$2@reader1.panix.com> |
| In reply to | #47493 |
On 12/21/2016 04:39 PM, Paavo Helde wrote: > alse sharing as the slicing size 10 is most probably not divisible by > the cache line size, thus causing potentially significant performance > penalties (probably not important for your toy example, but worth to > mention). That is a VERY cool observation!!! Thank You
[toc] | [prev] | [next] | [standalone]
| From | "Chris M. Thomasson" <invalid@invalid.invalid> |
|---|---|
| Date | 2016-12-23 15:19 -0800 |
| Message-ID | <o3kbbl$348$1@dont-email.me> |
| In reply to | #47506 |
On 12/21/2016 8:49 PM, ruben safir wrote: > On 12/21/2016 04:39 PM, Paavo Helde wrote: >> alse sharing as the slicing size 10 is most probably not divisible by >> the cache line size, thus causing potentially significant performance >> penalties (probably not important for your toy example, but worth to >> mention). > > > That is a VERY cool observation!!! > > Thank You > Agreed. False sharing is the root of all evil wrt multi-thread/processing. What good is a slick use of atomics if the data-structures are not properly padded up to, and allocated in memory on properly aligned cache lines? False sharing will totally ruin any chance of a possible speed up wrt atomic's.
[toc] | [prev] | [next] | [standalone]
| From | Sal LO <gegefffffff@gmail.com> |
|---|---|
| Date | 2016-12-22 07:04 -0800 |
| Message-ID | <bb9d52b6-69f5-4090-b67e-ed1135c3d2dd@googlegroups.com> |
| In reply to | #47488 |
On Wednesday, December 21, 2016 at 10:49:05 PM UTC+2, Popping mad wrote:
> :(
>
> I don't know. I'm very confused about the behavior of this test program I've been right.
> I'm trying to move date by worker threads from one blob of memory to another and the debugger
> is saying that the pointers beg and canvas_index is jumping 10 bytes between this two lines
>
> for(int i = 0; i < 10;i++)
> {
> t[i] = std::thread([this]{ readin(beg, canvas_index); });
>
> and I'm not sure why. I lost the concurrency somewhere, but can't seem to figure out what I did wrong
>
>
> #include <iostream>
> #include <thread>
> #include <mutex>
> std::mutex medco;
> std::mutex master;
>
> namespace testing{
> std::thread t[10];
> class PIC
> {
> public:
> PIC():beg{&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(beg, canvas_index); });
> std::cerr << i << ": Making a thread" << std::endl;
> sync_canvas_and_input();
> }
> };
>
> void sync_canvas_and_input()
> {
> std::cout << "**LOCKING**" << std::endl;
> std::lock_guard<std::mutex> turn(medco);
> beg += 10;
> canvas_index += 10;
> }
>
> ~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 * start, char * loc_canvas_index)
> {
> for( int i = 9; i>=0; i-- )
> {
> *loc_canvas_index = start[i];
> std::cerr << i << ": Copy " << start[i] << std::endl;
> std::cerr << i << ": Copied to loc_canvas_index " << reinterpret_cast<char>(*loc_canvas_index) << std::endl;
> loc_canvas_index++;
> }
https://youtu.be/Al9bmstjUjc?t=2s
[toc] | [prev] | [next] | [standalone]
| From | ruben safir <ruben@mrbrklyn.com> |
|---|---|
| Date | 2016-12-22 11:00 -0500 |
| Message-ID | <o3gtbp$pu8$1@reader1.panix.com> |
| In reply to | #47514 |
> > https://youtu.be/Al9bmstjUjc?t=2s > I'm deaf and can't hear videos, but thanks.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c++
csiph-web