Passing parameters in threads

Pages: 12
No, it has to be posix threads. Win32 threads don't work last time I checked, hence the need for the winpthreads library. Make sure that you have a command line option enabled for -pthread as well, to enable threading. To do that, go into your Build Options, Compiler Options, Other Options and add it in.
Ahh, it throws the same error as before, I have every setting like the picture you've shown me but it still doesn't work. I have windows, should I have chosen


Should work. You probably specified the wrong path or didn't choose the compiler for the project in build options.

Make sure that you have a command line option enabled for -pthread as well, to enable threading.


I didn't have to do this in my environment for some reason.
IT WORKS, THANK YOU!

NT3, your thing worked :D

htirwin:

1
2
3
4
5
6
7
8
9
10
11

mingw32-g++.exe -Wall -fexceptions -g -std=c++11 -Wextra  -c "C:\Users\cocon_000\Desktop\C++\PrimeArgsThreading\main.cpp" -o obj\Debug\main.o
C:\Users\cocon_000\Desktop\C++\PrimeArgsThreading\main.cpp: In function 'int main()':
C:\Users\cocon_000\Desktop\C++\PrimeArgsThreading\main.cpp:66:5: error: cannot convert 'long unsigned int*' to 'void* const*' for argument '2' to 'DWORD WaitForMultipleObjects(DWORD, void* const*, BOOL, DWORD)'
C:\Users\cocon_000\Desktop\C++\PrimeArgsThreading\main.cpp: In function 'int main()':
C:\Users\cocon_000\Desktop\C++\PrimeArgsThreading\main.cpp:76:5: error: redefinition of 'int main()'
C:\Users\cocon_000\Desktop\ C++\PrimeArgsThreading\main.cpp:41:5: error: 'int main()' previously defined here
C:\Users\cocon_000\Desktop\C++\PrimeArgsThreading\main.cpp:104:5: error: cannot convert 'long unsigned int*' to 'void* const*' for argument '2' to 'DWORD WaitForMultipleObjects(DWORD, void* const*, BOOL, DWORD)'
Process terminated with status 1 (0 minute(s), 2 second(s))
4 error(s), 0 warning(s) (0 minute(s), 2 second(s))


Your example, I figured out that you need
#include <windows.h>

but now I'm getting these errors :/
Last edited on
You'll need to manually cast them - AFAIK, it would work in C, but C++ removed those kinds of implicit casts to and from void*.
How do you cast an object? also, what's AFAIK?
To cast an object, the easiest (C-Style) way is to do this:(type)parameter;. In this case:
1
2
3
4
5
6
WaitForMultipleObjects(
    4,
    (void*)handles, // or reinterpret_cast<void*>(handles) for C++ way
    TRUE,
    INFINITE
);


AFAIK = As Far As I Know
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

mingw32-g++.exe -Wall -fexceptions -pthread -g -std=c++11 -Wextra  -c "C:\Desktop\C++\PrimeArgsThreading\main.cpp" -o obj\Debug\main.o
C:\Desktop\C++\PrimeArgsThreading\main.cpp: In function 'int main()':
C:\Desktop\C++\PrimeArgsThreading\main.cpp:66:5: error: invalid conversion from 'void*' to 'void* const*' [-fpermissive]
In file included from c:\program files (x86)\codeblocks\mingw\bin\../lib/gcc/mingw32/4.7.1/../../../../include/windows.h:50:0,
                 from C:\Desktop\C++\PrimeArgsThreading\main.cpp:4:
c:\program files (x86)\codeblocks\mingw\bin\../lib/gcc/mingw32/4.7.1/../../../../include/winbase.h:2199:25: error:   initializing argument 2 of 'DWORD WaitForMultipleObjects(DWORD, void* const*, BOOL, DWORD)' [-fpermissive]
C:\Desktop\C++\PrimeArgsThreading\main.cpp: In function 'int main()':
C:\Desktop\C++\PrimeArgsThreading\main.cpp:76:5: error: redefinition of 'int main()'
C:\Users\cocon_000\Desktop\Daniel Pham's C++\PrimeArgsThreading\main.cpp:41:5: error: 'int main()' previously defined here
C:\Desktop\C++\PrimeArgsThreading\main.cpp:104:5: error: invalid conversion from 'void*' to 'void* const*' [-fpermissive]
In file included from c:\program files (x86)\codeblocks\mingw\bin\../lib/gcc/mingw32/4.7.1/../../../../include/windows.h:50:0,
                 from C:\Desktop\C++\PrimeArgsThreading\main.cpp:4:
c:\program files (x86)\codeblocks\mingw\bin\../lib/gcc/mingw32/4.7.1/../../../../include/winbase.h:2199:25: error:   initializing argument 2 of 'DWORD WaitForMultipleObjects(DWORD, void* const*, BOOL, DWORD)' [-fpermissive]
Process terminated with status 1 (0 minute(s), 0 second(s))
6 error(s), 0 warning(s) (0 minute(s), 0 second(s))


I get this now when I try casting the handles
What do you think the errors mean?
:/ I think I can fix the 'void*' to 'void* const*' but... how do you fix 2 iterations of int main()?
how do you fix 2 iterations of int main()?

You can't have two main functions.

Here is a working version. I know it's contrived, it's just for testing threading.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

#include <iostream>
#include <windows.h>
#include <process.h>
#include <cmath>
#include <chrono>
#include <ctime>

struct PrimeSumArgs {

    unsigned long long sum;
    unsigned start;
    unsigned end;
};

bool isMerssenePrime( int n ) {

    if ( n < 2 )
        return false;

    int sqrtn = std::sqrt( n );
    for ( unsigned i = 2; i <= sqrtn; ++i ) {
        if ( n % i == 0 )
            return false;
    }

    return !( (n+1) & n );
}

unsigned __stdcall primeSum( void* _args ) {

    PrimeSumArgs *args = static_cast < PrimeSumArgs* >( _args );

    for( unsigned i = args->start; i <= args->end; ++i ) {
        if ( isMerssenePrime( i ) )
            args->sum += i;
    }

    return 0;
}

int main() {

    const int NUM_THREADS = 32;

    unsigned lim;
    std::cout << "how far out?\n";
    std::cin >> lim;

    int workSize = lim / NUM_THREADS;

    PrimeSumArgs args[ NUM_THREADS ];

    for ( unsigned i = 0; i < NUM_THREADS; ++i ) {
        args[i].sum = 0;
        args[i].start = i*workSize;
        args[i].end = ( i == NUM_THREADS - 1 ) ? lim : (  i + 1 ) * workSize - 1;
    }

    HANDLE handles[ NUM_THREADS ];

    std::chrono::time_point<std::chrono::system_clock> start = std::chrono::system_clock::now();

    for ( unsigned i = 0; i < NUM_THREADS; ++i ) {
        handles[i] = reinterpret_cast < HANDLE > ( _beginthreadex (
            NULL,
            0,
            primeSum,
            static_cast< void* >( &args[i] ),
            0,
            NULL
        ) );
    }

    WaitForMultipleObjects(
        NUM_THREADS,
        handles,
        TRUE,
        INFINITE
    );

    unsigned long long sum = 0;
    for ( int i = 0; i < NUM_THREADS; ++i )
        sum += args[i].sum;

    std::cout << "The sum of Merssene primes from between 1 and " << lim << " is " << sum
        << std::endl
        << "the calcuation took "
        << std::chrono::duration< double >( std::chrono::system_clock::now() - start ).count()
        << " second using " << NUM_THREADS << " threads"
        << std::endl;
}

Last edited on
I'm getting errors for your fixed version, if I don't have #include <process.h>
I'll get

_beginthreadex() was not declared in this scope

if I have #include <process.h>

then I get these:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

mingw32-g++.exe -Wall -fexceptions -pthread -g -std=c++11 -Wextra  -c "C:\Users\cocon_000\Desktop\Daniel Pham's C++\PrimeArgsThreading\main.cpp" -o obj\Debug\main.o
C:\Users\cocon_000\Desktop\Daniel Pham's C++\PrimeArgsThreading\main.cpp: In function 'bool isMerssenePrime(int)':
C:\Users\cocon_000\Desktop\Daniel Pham's C++\PrimeArgsThreading\main.cpp:21:32: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
C:\Users\cocon_000\Desktop\Daniel Pham's C++\PrimeArgsThreading\main.cpp: In function 'int main()':
C:\Users\cocon_000\Desktop\Daniel Pham's C++\PrimeArgsThreading\main.cpp:53:31: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
C:\Users\cocon_000\Desktop\Daniel Pham's C++\PrimeArgsThreading\main.cpp:63:31: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
C:\Users\cocon_000\Desktop\Daniel Pham's C++\PrimeArgsThreading\main.cpp:71:9: error: invalid conversion from 'unsigned int (*)(void*)' to 'unsigned int (__attribute__((__stdcall__)) *)(void*)' [-fpermissive]
In file included from C:\Users\cocon_000\Desktop\Daniel Pham's C++\PrimeArgsThreading\main.cpp:3:0:
c:\program files (x86)\codeblocks\mingw\bin\../lib/gcc/mingw32/4.7.1/../../../../include/process.h:100:2: error:   initializing argument 3 of 'long unsigned int _beginthreadex(void*, unsigned int, unsigned int (__attribute__((__stdcall__)) *)(void*), void*, unsigned int, unsigned int*)' [-fpermissive]
Process terminated with status 1 (0 minute(s), 1 second(s))
2 error(s), 3 warning(s) (0 minute(s), 1 second(s))
 
You have to change this,

unsigned primeSum( void* _args ) {

to

unsigned __stdcall primeSum( void* _args ) {

I was compiling with my mingw-builds compiler and for some reason it didn't throw any errors.
Thanks! it works now :D

now I just need to analyze how all of these work .-.
Last edited on
Topic archived. No new replies allowed.
Pages: 12