[c++] Program wielowątkowy, bład kompilacji


(fedora24x) #1

Witam, pisze program sprzawdzajcy czy dana liczba jest liczba pierwszą, sprawdzając i licząc jej dzielniki. Program nie chce sie z kompilować. Nie wiem co jest źle.
#include <stdio.h>
#include
#include
using namespace std;
void IsPrime(int Number)
{
register int CountOfDivides = 0;

    			thread th1([](int& CountOfDivides, int Number)->void{
    				for (register int i = (int)(Number*0.75); i <= (int)(Number*1); i++)
    					if((Number%i) == 0)
    				CountOfDivides++;
    			}(CountOfDivides, Number), CountOfDivides, Number);
    			thread th2([](int& CountOfDivides, int Number)->void{
    				for (register int i = (int)(Number*0.5); i <= (int)(Number*0.75); i++)
    					if((Number%i) == 0)
    				CountOfDivides++;
    		}(CountOfDivides, Number), CountOfDivides, Number);
    			thread th3([](int& CountOfDivides, int Number)->void{
    				for (register int i = (int)(Number*0.25); i <= (int)(Number*0.5); i++)
    					if((Number%i) == 0)
    				CountOfDivides++;
    		}(CountOfDivides, Number), CountOfDivides, Number);
    			thread th4([](int& CountOfDivides, int Number)->void{
    				for (register int i = 1; i <= (int)(Number*0.25); i++)
    					if((Number%i) == 0)
    				CountOfDivides++;
    			}(CountOfDivides, Number), CountOfDivides, Number);
    			th1.join();
    			th2.join();
    			th3.join();
    			th4.join();
    			
    	if (CountOfDivides == 2)
    		printf("%8d\n", Number);
    }
    int main(int argc, char const *argv[])
    {
    	register int Number = 1000000000;
    	IsPrime(Number);
    	return 0;
    }

(Fizyda) #3

Podałbyś chociaż błąd kompilacji …


(fedora24x) #4

Compiling project changes…

  • Project Filename: C:\Users\Ra\Desktop\Ra\RR\Project1.dev
  • Compiler Name: TDM-GCC 4.9.2 64-bit Release

Building makefile…

  • Filename: C:\Users\Ra\Desktop\Ra\RR\Makefile.win

Processing makefile…

  • Makefile Processor: %BinDir0%\mingw32-make.exe
  • Command: mingw32-make.exe -f “C:\Users\Ra\Desktop\Ra\RR\Makefile.win” all

g++.exe -std=c++11 -O0 -D__DEBUG__ -c main.cpp -o main.o -I"%CppIncludeDir0%" -I"%CppIncludeDir1%" -I"%CppIncludeDir2%" -I"%CppIncludeDir2%\c++" -g3

main.cpp: In function ‘void IsPrime(int)’:
main.cpp:13:53: error: invalid use of void expression
}(CountOfDivides, Number), CountOfDivides, Number);
^

main.cpp:18:52: error: invalid use of void expression
}(CountOfDivides, Number), CountOfDivides, Number);
^
main.cpp:23:52: error: invalid use of void expression
}(CountOfDivides, Number), CountOfDivides, Number);
^
main.cpp:28:53: error: invalid use of void expression
}(CountOfDivides, Number), CountOfDivides, Number);
^

C:\Users\Ra\Desktop\Ra\RR\Makefile.win:28: recipe for target ‘main.o’ failed

mingw32-make.exe: *** [main.o] Error 1


(fedora24x) #6

Rozbijam proces sprawdzania dzielników mna 4 równe zakresy, a kazdy zakres wrzucam w watki, gdzie funkcja jest wyrazenie delta


(Fizyda) #7

Napisałeś kod w tak nieczytelny sposób, że trochę zajęło mi ogarnięcie go i zrozumienie, tym bardziej, że nie jestem jakimś masterem C++, a wręcz przeciwnie, nawet nie do końca znam standardy C++11/14, a żeby było śmieszniej średnio na jeża ogarniam programowanie wielowątkowe. Jednak widzę prawdopodobnie błąd.

Gdy bardziej po ludzku napisze się kod jego fragment będzie wyglądał następująco:

thread th2(
	[](int& CountOfDivides, int Number)->void {
		for (register int i = (int)(Number*0.5); i <= (int)(Number*0.75); i++)
			if((Number%i) == 0)
		CountOfDivides++;
	} (CountOfDivides, Number),
	CountOfDivides,
	Number
);

Teraz widać, że wywołujesz funkcję w miejscu gdzie powinieneś ją przekazać, niepotrzebnie masz (CountOfDivides, Number) po definicji funkcji lambda.

Druga sprawa jest taka, że powielasz 4 razy ten sam kod, tworzenie wątków powinieneś zrobić w pętli i przechowywać ich adresy w tablicy, a nie zmiennych.


(fedora24x) #8

Tak powtarzam kod 4 razy, dziele zakres liczb od zera do Number, na 4 równe części, a kazda cześć przeszukuje oddzielny wątek szukając dzielników.


(Fizyda) #9

Tyle, że możesz to zrobić w pętli albo nawet w funkcji i przekazać tylko zakres dla danego wątku.