Creating an array of objects causes an issue - c++

I create the two following objects:
bool Reception::createNProcess()
{
for (int y = 0; y < 3; ++y)
{
Process *pro = new Process; // forks() at construction
Thread *t = new Thread[5];
this->addProcess(pro); // Adds the new process to a vector
if (pro->getPid() == 0)
{
for (int i = 0; i < 5; ++i)
{
pro->addThread(&t[i]); // Adds the new thread to a vector
t[i].startThread();
}
}
}
Where I create 3 processes (that I have encapsulated in Process) and create 5 threads in each of these processes.
But I'm not sure the following line is correct:
Thread *t = new Thread[5];
Because my two functions addProcess and addThread both take a pointer to Process and Thread respectively and yet the compiler asks for a reference to t[i] for addThread and I don't understand why.
void Process::addThread(Thread *t)
{
this->threads_.push_back(t);
}
void Reception::addProcess(Process *p)
{
this->createdPro.push_back(p);
}
createdPro is defined in the Reception class as follows:
std::vector<Process *> createdPro;
and threads_ in the Process class like such:
std::vector<Thread *> threads_;
And the error message (as obvious as it is) is as follows:
error: no matching function for call to ‘Process::addThread(Thread&)’
pro->addThread(t[i]);
process.hpp:29:10: note: candidate: void Process::addThread(Thread*)
void addThread(Thread *);
process.hpp:29:10: note: no known conversion for argument 1 from ‘Thread’ to ‘Thread*’
Even though I defined my Thread as a pointer.

You have defined the member function to take a pointer:
void Process::addThread(Thread *t)
{
...
}
You then invoke this function for &t[i], which is a pointer and should work perfectly:
pro->addThread(&t[i]); // Adds the new thread to a vector
You could also invoke it with t+i and it would still be ok. However your error message tells us something different: the compiler doesn't find a match for pro->addThread(t[i]); (i.e. the & is missing).
Either you made a typo in your question, or you made a typo in your code. Or you have another invocation somewhere where you've forgotten the ampersand: t[i] would of course designate an object (it's equivalent to *(t+i) ) and not a pointer, and cause the error message you have (demo mcve)

Related

C++ threads and variables

I have a problem within the program that I write. I have functions returning pointers and within the main() I want to run them in threads.
I'm able to execute the functions in threads:
double* SplitFirstArray_1st(double *arr0){
const UI arrSize = baseElements/4;
std::cout << "\n1st split: \n";
double *arrSplited1=nullptr;
arrSplited1 = new double [arrSize];
for(UI i=0; i<arrSize; i++){
arrSplited1 = arr0;
}
for(UI j=0; j< arrSize; ++j){
std::cout << arrSplited1[j] << " ";
}
return arrSplited1;
delete [] arrSplited1, arr0;
}
in main()
std::thread _th1(SplitFirstArray_1st, rootArr);
_th1.join();
The above is not what I'm after. I have another pointer:
*arrTh1=nullptr;
I would like to use it in a thread so it would be assigned with the value returned by my function SplitFirstArray_1st
arrTh1 = SplitFirstArray_1st(xxx);
Is such action is possible to be executed in a tread ?
Don't return the variable, pass a pointer to the variable and set the value at what this points too.
i.e.:
void set_int(int* toset) {
*toset = 4;
}
This works fine with things that are already pointers:
void set_ptr(int** toset) {
*toset = new int[4];
// ...
*toset[0] = 2;
}
You can know the data is safe to use if the function has returned.
Completely unrelated note:
return foo;
// No point placing code here unless you used goto as it won't get executed.
// Also: don't use goto.
}
Something like this:
std::thread _th1([&]() { arrTh1 = SplitFirstArray_1st(rootArr); });
Functions which start the thread cannot return values in a normal way. Therefore they should be declared as void.
Common way is to assign a protected global variable. You should protect one with mutexes (or other methods) to avoid races.
mutex m;
double *arrTh1 = nullptr;
double* aSplitFirstArray_1st(double *arr0){
...
m.lock();
arrTh1 = arrSplited1;
m.unlock();
}
When you use the pointer in other threads (including the main one), you need to protect the usage as well with the same mutex (or choose other methods).
and please, do not delete arrSopited1 and arr0. it will make the arrTh1 pointer unusable.
Note, if you use async functions, you could use futures to return values.

CPP std::thread attempt to use a deleted function

First of all, I want to say that i already made researches on the subject, but nothing relevant...
(Error creating std::thread on Mac OS X with clang: "attempt to use a deleted function")
(Xcode 7: C++ threads ERROR: Attempting to use a deleted function)
(xcode - "attempt to use a deleted function" - what does that mean?)
And here's my issue...:
clang error:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/thread:347:5: error: attempt to use a deleted function
__invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
And that's my code:
bool GenAI::loadAIs()
{
bool ret = true;
if (_nbThread > 1)
{
std::vector<std::thread> threads;
for (unsigned int i = 0; i < _nbThread; ++i)
threads.push_back(std::thread(static_cast<void (GenAI::*)(bool &, unsigned int)>(&GenAI::loadAIs), this, ret, i));
for (unsigned int i = 0; i < _nbThread; ++i)
threads[i].join();
}
else
loadAIs(ret, 0);
return ret;
}
// And the prototype of the function that i try to call
void GenAI::loadAIs(bool & ret, unsigned int iThread);
If some one could help me that'd be really helpful ! :)
Regards ;)
To pass reference to thread, you have to use std::reference_wrapper, that you can obtain with std::ref. So your code becomes:
threads.emplace_back(static_cast<void (GenAI::*)(bool &, unsigned int)>(&GenAI::loadAIs),
this,
std::ref(ret),
i));
Note:
bool ret should probably be std::atomic<bool> ret, or should should have one bool by thread. Else you may have concurrent access on ret.
The deleted function that it is complaining about is a deleted copy constructor for const thread.
For the deleted function problem, you can use:
threads.emplace_back(
Instead of:
threads.push_back(
What the commenter also referred to is that the function is creating more than one thread and passing to them a reference to the same boolean return variable.
It will crash if you don't use atomic_bool and even if you do, they will all report back to the same memory location, making the function miss the notification if one of them returns false.

Cannot carry object to function properly C++

cliques is my class object. All my class commands work when I use them in my main but for some reason I cannot make changes to my heaps or stacks through my functions. I tried using reference markers on my function parameters but still I'm having ussues. Maybe I've done the reference incorrectly. Does anyone have any ideas what I might be doing wrong?
This is one of my functions:
void UpdateTopK(cliques C, vector<cliques> minheap) {
if (C.getclique_size() < CliqueSize) {
return;
}
else if (minheap.size() < Solutions) {
minheap.push_back(C);
push_heap(minheap.begin(), minheap.end(), min_iterator());
}
else if (minheap.size() == Solutions and C.getMaxclique_prob() > minheap.front().getMaxclique_prob()) {
pop_heap(minheap.begin(), minheap.end(), min_iterator());
minheap.pop_back();
minheap.push_back(C);
push_heap(minheap.begin(), minheap.end(), min_iterator());
}
This is part of my main:
stack <cliques> cstack;
vector<cliques> max_heap;
make_heap(max_heap.begin(), max_heap.end(), max_iterator());
vector<cliques> min_heap;
make_heap(min_heap.begin(), min_heap.end(), min_iterator());
for (int i = 0; i < 5; i++) {
cliques temp(i);
cstack.push(temp);
}
while (!cstack.empty()) {
cliques temp = cstack.top();
cstack.pop();
bool pruned = GenerateChildren(temp, min_heap, max_heap, cstack, graph);
if (!pruned) {
UpdateTopK(temp, min_heap);
}
}
You are passing arguments by value, this implies that parameters are copied before being passed to the function.
So every modification inside a method refers to the local copy only. Try passing values by references, eg:
void UpdateTopK(cliques& C, vector<cliques>& minheap)
^ ^
Mind that an object that needs to be passed to a function without copy and without being edited should be passed by const T& to specify this.

Attempt to use a deleted function

From what I can gather online the cause of this is most likely related to trying to copy a thread (which you can't do). I'm not sure why this problem is arising though. I do suspect which lines it arises in though.
Worker thread definition:
void WorkerThread(SharedLList<uint32_t> *workQueue, std::mutex *dataLock, uint8_t *data, uint32_t *seenStates, int depth)
Code in calling function:
SharedLList<uint32_t> workQueue;
std::mutex lock;
uint8_t *stateDepths = new uint8_t[s.GetMaxRank()];
uint32_t seenStates = 1;
int currDepth = 0;
for (int i = 0; i < numThreads; i++)
{
threads[i] = new std::thread(WorkerThread, std::ref(workQueue), std::ref(lock), stateDepths, std::ref(seenStates), currDepth);
}
Thread
-> Semantic Issue
-> Attempt to use a deleted function
This is the line:
__invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
How can I fix this issue? What is wrong with my code?
Your thread function is declared as accepting pointers as parameters. Yet you pass references as arguments. This mismatch exists for all pointer parameters except uint8_t *data.

Multithreaded matrix multiplication in C++

I've been having trouble with this parallel matrix multiplication code, I keep getting an error when trying to access a data member in my structure.
This is my main function:
struct arg_struct
{
int* arg1;
int* arg2;
int arg3;
int* arg4;
};
int main()
{
pthread_t allthreads[4];
int A [N*N];
int B [N*N];
int C [N*N];
randomMatrix(A);
randomMatrix(B);
printMatrix(A);
printMatrix(B);
struct arg_struct *args = (arg_struct*)malloc(sizeof(struct arg_struct));
args.arg1 = A;
args.arg2 = B;
int x;
for (int i = 0; i < 4; i++)
{
args.arg3 = i;
args.arg4 = C;
x = pthread_create(&allthreads[i], NULL, &matrixMultiplication, (void*)args);
if(x!=0)
exit(1);
}
return 0;
}
and the matrixMultiplication method used from another C file:
void *matrixMultiplication(void* arguments)
{
struct arg_struct* args = (struct arg_struct*) arguments;
int block = args.arg3;
int* A = args.arg1;
int* B = args.arg2;
int* C = args->arg4;
free(args);
int startln = getStartLineFromBlock(block);
int startcol = getStartColumnFromBlock(block);
for (int i = startln; i < startln+(N/2); i++)
{
for (int j = startcol; j < startcol+(N/2); j++)
{
setMatrixValue(C,0,i,j);
for(int k = 0; k < N; k++)
{
C[i*N+j] += (getMatrixValue(A,i,k) * getMatrixValue(B,k,j));
usleep(1);
}
}
}
}
Another error I am getting is when creating the thread: "invalid conversion from ‘void ()(int, int*, int, int*)’ to ‘void* ()(void)’ [-fpermissive]
"
Can anyone please tell me what I'm doing wrong?
First you mix C and C++ very badly, either use plain C or use C++, in C++ you can simply use new and delete.
But the reason of your error is you allocate arg_struct in one place and free it in 4 threads. You should allocate one arg_struct for each thread
Big Boss is right in the sense that he has identified the problem, but to add to/augment the reply he made.
Option 1:
Just create an arg_struct in the loop and set the members, then pass it through:
for(...)
{
struct arg_struct *args = (arg_struct*)malloc(sizeof(struct arg_struct));
args->arg1 = A;
args->arg2 = B; //set up args as now...
...
x = pthread_create(&allthreads[i], NULL, &matrixMultiplication, (void*)args);
....
}
keep the free call in the thread, but now you could then use the passed struct directly rather than creating locals in your thread.
Option 2:
It looks like you want to copy the params from the struct internally to the thread anyway so you don't need to dynamically allocate.
Just create an arg_struct and set the members, then pass it through:
arg_struct args;
//set up args as now...
for(...)
{
...
x = pthread_create(&allthreads[i], NULL, &matrixMultiplication, (void*)&args);
}
Then remove the free call.
However as James pointed out you would need to synchronize in the thread/parent on the structure to make sure that it wasn't changed. That would mean a Mutex or some other mechanism. So probably the move of the allocation to the for loop is easier to begin with.
Part 2:
I'm working on windows (so I can't experiment currently), but pthread_create param 3 is referring to the thread function matrixMultiplication which is defined as void* matrixMultiplication( void* ); - it looks correct to me (signature wise) from the man pages online, void* fn (void* )
I think I'll have to defer to someone else on your second error. Made this post a comunnity wiki entry so answer can be put into this if desired.
It's not clear to me what you are trying to do. You start some threads,
then you return from main (exiting the process) before getting any
results from them.
In this case, I'ld probably not use any dynamic allocation, directly.
(I would use std::vector for the matrices, which would use dynamic
allocation internally.) There's no reason to dynamically allocate the
arg_struct, since it can safely be copied. Of course, you'll have to
wait until each thread has successfully extracted its data before
looping to construct the next thread. This would normally be done using
a conditional: the new thread would unblock the conditional once it has
extracted the arguments from the arg_struct (or even better, you could
use boost::thread, which does this part for you). Alternatively, you
could use an array of arg_struct, but there is absolutely no reason to
allocate them dynamically. (If for some reason you cannot use
std::vector for A, B and C, you will want to allocate these
dynamically, in order to avoid any risk of stack overflow. But
std::vector is a much better solution.)
Finally, of course, you must wait for all of the threads to finish
before leaving main. Otherwise, the threads will continue working on
data that doesn't exist any more. In this case, you should
pthread_join all of the threads before exiting main. Presumably,
too, you want to do something with the results of the multiplication,
but in any case, exiting main before all of the threads have finished
accessing the matrices will cause undefined behavior.