trying to learn _beginthreadex and passing parameters - multithreading

copying some data I had for working boost threads, I implemented the following code below.
I get the error C:\dev\default threads_threads.cpp|18|error: invalid conversion from 'void ()(void)' to 'unsigned int (attribute((stdcall)) )(void)' [-fpermissive]|
but... the commented lines are what was recommended, and a comment explains the error I got.
it turns out _beginThreadEx is highly recommended, but poorly documented (as in tutorials) on the web
#include <iostream>
#include <process.h>
void myThread(void *data)
{
//C:\dev\default threads\_threads.cpp|6|error: invalid conversion from 'int*' to 'int' [-fpermissive]|
//int x = static_cast<int*>(data);
int *x = (int*)data;
std::cout << "Hellow World! " << x;
}
int main()
{
int x = 10;
_beginthreadex(NULL, 0, myThread, &x, 0, NULL);
while(true);
}

You have to declare x as pointer anyway:
int *x = static_cast<int*>(data);
both _beginthread and _beginthreadex are documented here: http://msdn.microsoft.com/en-us/library/kdzttdcb(v=vs.80).aspx
According to the declaration of _beginthreadex() your myThread() function should be declared like this:
unsigned __stdcall myThread(void *data);

Related

std::max giving error C2064: term does not evaluate to a function taking 2 arguments

I am fairly new to C++. I was practicing some ds,algo.This code looks fine to me, but I am getting some error about function not taking 2 arguments. Though I get some error asked in stackoverflow none of the cases match my problem.
#include <iostream>
#include <algorithm>
int ropecutting(int n, int *cuts){
if (n == 0)
return 0;
if (n < 0)
return -1;
int res = std::max(ropecutting(n-cuts[0], cuts), ropecutting(n-cuts[1], cuts), ropecutting(n-cuts[2], cuts));
if(res == -1) return -1;
return res+1;
}
int main(){
int n, cuts[3];
std::cin >> n;
for(int i = 0; i < 3; i ++)
std::cin >> cuts[i];
std::cout << ropecutting(n, cuts);
}
The error I get is,
main.cpp
G:\software_installation\Visual Studio Community 2017\VC\Tools\MSVC\14.16.27023\include\xlocale(319): warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc
G:\software_installation\Visual Studio Community 2017\VC\Tools\MSVC\14.16.27023\include\algorithm(5368): error C2064: term does not evaluate to a function taking 2 arguments
G:\software_installation\Visual Studio Community 2017\VC\Tools\MSVC\14.16.27023\include\algorithm(5367): note: see reference to function template instantiation 'const _Ty &std::max<int,int>(const _Ty &,const _Ty &,_Pr) noexcept(<expr>)' being compiled
with
[
_Ty=int,
_Pr=int
]
G:\software_installation\Visual Studio Community 2017\VC\Tools\MSVC\14.16.27023\include\algorithm(5368): error C2056: illegal expression
Wishing someone would point me out in the right direction. Thank you.
Of the overloads of std::max, the only one which can be called with three arguments is
template < class T, class Compare >
constexpr const T& max( const T& a, const T& b, Compare comp );
So since it receives three int values, that function is attempting to use the third value as a functor to compare the other two, which of course doesn't work.
Probably the simplest way to get the maximum of three numbers is using the overload taking a std::initializer_list<T>. And a std::initializer_list can be automatically created from a braced list:
int res = std::max({ropecutting(n-cuts[0], cuts),
ropecutting(n-cuts[1], cuts),
ropecutting(n-cuts[2], cuts)});

Pass multiple args to thread using struct (pthread)

I'm learning to programming using pthread for a adder program, after reference several codes still don't get how to pass multiple arguments into a thread using a struct, here is my buggy program:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
typedef struct s_addition {
int num1;
int num2;
int sum;
} addition;
void *thread_add_function (void *ad)
{
printf ("ad.num1:%d, ad.num2:%d\n",ad.num1, ad.num2);
ad.sum = ad.num1 + ad.num2;
pthread_exit(0);
}
int main()
{
int N = 5;
int a[N], b[N], c[N];
srand (time(NULL));
// fill them with random numbers
for ( int j = 0; j < N; j++ ) {
a[j] = rand() % 392;
b[j] = rand() % 321;
}
addition ad1;
pthread_t thread[N];
for (int i = 0; i < N; i++) {
ad1.num1 = a[i];
ad1.num2 = b[i];
printf ("ad1.num1:%d, ad1.num2:%d\n",ad1.num1, ad1.num2);
pthread_create (&thread[i], NULL, thread_add_function, &ad1);
pthread_join(thread[i], NULL);
c[i] = ad.sum;
}
printf( "This is the result of using pthread.\n");
for ( int i = 0; i < N; i++) {
printf( "%d + %d = %d\n", a[i], b[i], c[i]);
}
}
But when compiling I got the following error:
vecadd_parallel.c:15:39: error: member reference base type 'void *' is not a
structure or union
printf ("ad.num1:%d, ad.num2:%d\n",ad.num1, ad.num2);
I tried but still cannot get a clue, what I am doing wrong with it?
Seems like you have a problem with trying to access the members of a void datatype.
You will need to add a line to cast your parameter to thread_add_function to the correct datatype similar to addition* add = (addition*)ad;, and then use this variable in your function (note that you also have to change you r .'s to -> because it's a pointer)
You also should only pass data to threads that was malloc()'d, as stack allocated data may not be permanent. It should be fine for the current implementation, but changes later could easily give strange, unpredictable behaviour.

Pthread create function

I am having difficulty understanding the creation of a pthread.
This is the function I declared in the beginning of my code
void *mini(void *numbers); //Thread calls this function
Initialization of thread
pthread_t minThread;
pthread_create(&minThread, NULL, (void *) mini, NULL);
void *mini(void *numbers)
{
min = (numbers[0]);
for (i = 0; i < 8; i++)
{
if ( numbers[i] < min )
{
min = numbers[i];
}
}
pthread_exit(0);
}
numbers is an array of integers
int numbers[8];
Im not sure if I created the pthread correctly.
In the function, mini, I get the following error about setting min (declared as an int) equal to numbers[0]:
Assigning to 'int' from incompatible type 'void'
My objective is to compute the minimum value in numbers[ ] (min) in this thread and use that value later to pass it to another thread to display it. Thanks for any help I can get.
You need to pass 'numbers' as the last argument to pthread_create(). The new thread can then call 'mini' on its own stack with 'numbers' as the argument.
In 'mini', you shoudl cast the void* back to an integer array in order to dereference it correctly - you cannot dereference a void* directly - it does not point to anything:)
Also, it's very confusing to have multiple vars in different threads with the name 'numbers'.
There are some minor improprieties in this pgm but it illustrates basically what you want to do. You should play around, break and improve it.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *mini(void *numbs)
{
int *numbers = (int *) numbs;
int *min = malloc(sizeof(int));
*min = (numbers[0]);
for (int i = 0; i < 8; i++)
if (numbers[i] < *min )
*min = numbers[i];
pthread_exit(min);
}
int main(int argc, char *argv[])
{
pthread_t minThread;
int *min;
int numbers[8] = {28, 47, 36, 45, 14, 23, 32, 16};
pthread_create(&minThread, NULL, (void *) mini, (void *) numbers);
pthread_join(minThread, (void *) &min);
printf("min: %d\n", *min);
free(min);
return(0);
}

C++/CLI from tracking reference to (native) reference - wrapping

I need a C# interface to call some native C++ code via the CLI dialect. The C# interface uses the out attribute specifier in front of the required parameters. That translates to a % tracking reference in C++/CLI.
The method I has the following signature and body (it is calling another native method to do the job):
virtual void __clrcall GetMetrics(unsigned int %width, unsigned int %height, unsigned int %colourDepth, int %left, int %top) sealed
{
mRenderWindow->getMetrics(width, height, colourDepth, left, top);
}
Now the code won't compile because of a few compile time errors (all being related to not being able to convert parameter 1 from 'unsigned int' to 'unsigned int &').
As a modest C++ programmer, to me CLI is looking like Dutch to a German speaker. What can be done to make this wrapper work properly in CLI?
Like it was also suggested in a deleted answer, I did the obvious and used local variables to pass the relevant values around:
virtual void __clrcall GetMetrics(unsigned int %width, unsigned int %height, unsigned int %colourDepth, int %left, int %top) sealed
{
unsigned int w = width, h = height, c = colourDepth;
int l = left, t = top;
mRenderWindow->getMetrics(w, h, c, l, t);
width = w; height = h; colourDepth = c; left = l; top = t;
}
It was a bit obvious since the rather intuitive mechanism of tracked references: they're affected by the garbage collector's work and are not really that static/constant as normal &references when they're prone to be put somewhere else in memory. Thus this is the only way reliable enough to overcome the issue. Thanks to the initial answer.
If your parameters use 'out' on the C# side, you need to define your C++/CLI parameters like this: [Out] unsigned int ^%width
Here's an example:
virtual void __clrcall GetMetrics([Out] unsigned int ^%width)
{
width = gcnew UInt32(42);
}
Then on your C# side, you'll get back 42:
ValueType vt;
var res = cppClass.GetMetrics(out vt);
//vt == 42
In order to use the [Out] parameter on the C++/CLI side you'll need to include:
using namespace System::Runtime::InteropServices;
Hope this helps!
You can use pin_ptr so that 'width' doesn't move when native code changes it. The managed side suffers from pin_ptr, but I don't think you can get around that if you want native code directly access it without 'w'.
virtual void __clrcall GetMetrics(unsigned int %width, unsigned int %height, unsigned int %colourDepth, int %left, int %top) sealed
{
pin_ptr<unsigned int> pw = &width; //do the same for height
mRenderWindow->getMetrics(*pw, h, c, l, t);
}

Error initializing XGCValues

I was following this tutorial, bit stuck here:
This code doesn't compile, and the error message is
c:35: error: invalid initializer
I'm not sure what's wrong with the line
XGCValues valu=CapButt|JoinBevel;
infact, I copied it from the said tutorial. Here's the full code I have:
#include <stdio.h>
#include <X11/Xlib.h>
#include <unistd.h>
int main()
{
Display *display=XOpenDisplay(NULL);
int scr=DefaultScreen(display);
Window root_window=RootWindow(display,scr);
unsigned int width=DisplayWidth(display,scr)/3;
unsigned int height=DisplayHeight(display,scr)/3;
unsigned int border=2;
Window my_win=XCreateSimpleWindow(display,root_window,0,0,width,height,border,BlackPixel(display,scr),WhitePixel(display,scr));
GC gc;
XGCValues valu=CapButt|JoinBevel;
unsigned long valmask=GCCapStyle|GCJoinStyle;
gc=XCreateGC(display,my_win,valmask,&valu);
XDrawLine(display,my_win,gc,5,5,20,20);
XMapWindow(display,my_win);
XFlush(display);
sleep(10);
return 0;
}
Thank You
The example in the tutorial is wrong - if you look in <X11/Xlib.h> or read the XCreateGC man page you'll see XGCValues is a struct, not a integral type, so you would need to initialize it with something like:
XGCValues values;
values.cap_style = CapButt;
values.join_style = JoinBevel;

Resources