#how does multitreading memory work in c++?
123 messages · Page 1 of 1 (latest)
When your question is answered use !solved to mark the question as resolved.
Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question run !howto ask.
your question is way too broad
first you need a single-threaded solution, then you need to think how to distribute the work into N threads, then you gotta learn the std::thread syntax, and then implement a multithreaded solution
!asan
Sanitizers are tools which generate additional code in your program that can catch many common programming mistakes, such as:
- accessing arrays out of bounds (caught by ASan)
- signed integer overflows (caught by UBSan)
- data races (caught by ThreadSan)
- accessing indeterminate memory (caught by MemorySan)
Not all sanitizers can be combined, but when they can, use e.g.:
-fsanitize=address,undefined to combine them. Always compile with debug info to get line numbers, variable names, etc.
- -fsanitize=address
- -fsanitize=undefined
- -fsanitize=thread
-gfor debug info
- -fsanitize=address
- -fsanitize=undefined
- -fsanitize=thread
- -fsanitize=memory
-gand llvm-symbolizer for debug info
- -fsanitize=address
-Zifor debug info
int main(void) {
int x;
return x;
}
SUMMARY: MemorySanitizer: use-of-uninitialized-value /tmp/test.cpp:3:5 in main
Exiting
(3:5 is the line and column of return)
also,
when you work with multi threading, global variables are shit (in general they are shit). Try to avoid them.
smallchange is also terribly implemented I think, everytime you call it, it creates
std::random_device rd;
std::mt19937 gen(rd());
this should be not inside the function body imo, and probably be thread_local
and some functions are static for whatever reason?
"are shit" here means, they cause race conditions, that corrupt your memory and cause crashes
doesn't putting it outside the function cause it to be the same number every time smallchanged() is called?
That’s obvious since you get the problem of interplay between treads but how do than replace them?
replace what
Global variables
create local variables in main, pass them by reference wherever you need them
create structs, class
no, you should probably lookup what that code actually does : D
the random device is being used to seed the mersenne twister
and the mersenne twister is a pseudo random number generator
;compile cpp
#include <iostream>
#include <random>
std::random_device rd;
std::mt19937 gen(rd());
int foo () {
std::uniform_int_distribution<> distrib(0, 15);
return distrib(gen);
}
int main() {
for (int i = 0; i < 5; i++)
{
std::cout << foo() << std::endl;
}
return 0;
}
15
3
8
15
1
so what your code is actually doing, is recreating a mersenne twister in every call as well as the random device
some stuff in your code is flawed, i.e. reversevariable1 which exists both as a global variable and as a local variable
prime example of why not to use globals
int reversevariable1 = randomIndex1; in your first function is doing nothing
;compile cpp
#include <iostream>
int x = 1;
void foo () {
int x = 2;
}
int main() {
foo();
std::cout << x;
return 0;
}
1
float _ = also wtf is this
I mean you probably think why im hating on this when all you asked about was multithreading
but adding multi threading to a program where the execution flow is difficult to understand is just a really bad idea
I know for maintenance but is not a program anybody else is going to work so sorry for making not very readable
But the _ is just a placeholder because I couldn’t read that long lines and as an inbetween step but I should probably put that together
it is supposed to be where I store an int for a something I changed like a undo button but instead of copying all the data I just store what was changed
#include <iostream>
float foo() {
float sum;
sum += 2;
return sum;
}
int main() {
std::cout << foo();
return 0;
}
also this code adds to an uninitialized value which is also bad..and i.e. valgrind will fire
I don’t understand
your line 43 is doing nothing...
int reversevariable1 = randomIndex1;
randomIndex1 will not be saved to your global reversevariable1
on line 87 you have a sum float and then you add something to the float
float sum;
int numVertices = argGraph.size();
for (int index = 0; index < numVertices; ++index) {
std::vector<int> shortestDistances = dijkstra(argGraph, index, argpositions);
for (int i = 0; i < numVertices; ++i) {
sum += argweights[i] * (shortestDistances[i] - Mydistance(i, index, argpositions));
}
}
return sum;
sum is uninitialized
a few lines down you do it correct, float sum = 0.0;
Why?
look here.
thats basically what you are doing, just in small
you need to drop the int which creates a new variable
also this global variable is useless
std::vector<int> weights;
it's doing nothing
also you are already creating position in main... just pass it as a parameter into renderingThread
vectorOfset is also not used
so, id say clean it up and remove all global variables and then try to add multithreading
I was going to change that sorry
would it be a good idea to put the global variables in a class and add small change and u to that class?
more like a struct, yes
call it struct graphState
or something
what is a struct exactly? (what problem does it solve?)
struct and class are almost identical, difference is class uses private by default and struct uses public
why did they come up with it
std::vector<int> is a class
imagine implementing it manually instead
no I mean a struct
it's the same as a class
but the fields are pubic by default
structs are usually for pod (plain old data) and classes in c++ enable all kind of OOP stuff like inheritance, which is not really possible with structs
imagine structs like a package, and classes could be a mailmen.
Package has a width, height and length (3d object) and probably a weight. Thats all which you need to describe a package so its POD.
A mailmen has methods and member variables like a store which holds all the packages he has to deliver
could you also add functions to structs?
yes
#include <iostream>
#include <random>
std::random_device rd;
std::mt19937 gen(rd());
float foo () {
std::uniform_int_distribution<> distrib(0, 1);
return distrib(gen);
}
int main() {
for (int i = 0; i < 5; i++)
{
std::cout << foo() << std::endl;
}
return 0;
}
hm
how does bot work
;compile cpp
#include <iostream>
#include <random>
std::random_device rd;
std::mt19937 gen(rd());
float foo () {
std::uniform_int_distribution<> distrib(0, 1);
return distrib(gen);
}
int main() {
for (int i = 0; i < 5; i++)
{
std::cout << foo() << std::endl;
}
return 0;
}```
0
1
1
0
0
hm
;compile cpp
// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
int main()
{
// Using srand() with time(0) to change
// the random values everytime
srand(time(0));
// Loop to check that we get different values
// on every iteration
for (int i = 0; i < 10; i++) {
// Typecasting the random value
// obtained into a double and
// then dividing it with RAND_MAX
cout << ((double)rand()) / RAND_MAX << endl;
}
return 0;
}```
0.483602
0.131687
0.104625
0.746465
0.831092
0.715225
0.826825
0.768559
0.61094
0.350964
;compile cpp
// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
int main()
{
// Using srand() with time(0) to change
// the random values everytime
srand(time(0));
// Loop to check that we get different values
// on every iteration
for (int i = 0; i < 10; i++) {
// Typecasting the random value
// obtained into a double and
// then dividing it with RAND_MAX
cout << ((double)rand()) / RAND_MAX << endl;
}
return 0;
}
;compile cpp
// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
int main()
{
// Using srand() with time(0) to change
// the random values everytime
srand(time(0));
// Loop to check that we get different values
// on every iteration
for (int i = 0; i < 10; i++) {
// Typecasting the random value
// obtained into a double and
// then dividing it with RAND_MAX
cout << ((double)rand()) / RAND_MAX << endl;
}
return 0;
}
;compile cpp
// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
int main()
{
// Using srand() with time(0) to change
// the random values everytime
srand(time(0));
float randnumb = (double)rand()) / RAND_MAX;
cout << randnumb;
return 0;
}```
<source>: In function 'int main()':
<source>:11:36: error: expected ',' or ';' before ')' token
11 | float randnumb = (double)rand()) / RAND_MAX;
| ^
Build failed
;compile cpp
// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
int main()
{
// Using srand() with time(0) to change
// the random values everytime
srand(time(0));
float randnumb = (double)rand() / RAND_MAX;
cout << randnumb;
return 0;
}```
0.562364
Can you please not go 5 steps back ?xd
Don’t use srand, namespace std, bits/stdc++, c style casts
Why?
- srand / rand, are fairly low quality random numbers, and often used wrongly. C++ random number facilities are more porfrull
using namespace std;universally considered bad practisch#include <bits/stdc++.h>non portable and non standard header that includes everything what is also undesirable- c style casts will cast whatever, C++ casts are much more restrictive what is beneficial
and to circle back to why structs / classes. They bundle variables and or functionality togheter in a logicall group what makes programming much easier, imagine if you only had loose variables, it would be absolutly miserable
how should I than do random numbers
You were generating random numbers fine before
Just the initialization should have been outside of the loop
what do you mean with initialise before the loop?
What was wrong with this?
Not before, outside of it
does it give a different value everytime you run it?
And I doubt that you truly want a different value every time you run it
;compile cpp
#include <iostream>
#include <random>
std::random_device rd;
std::mt19937 gen(rd());
float foo () {
std::uniform_float_distribution<> distrib(0, 1);
return distrib(gen);
}
int main() {
for (int i = 0; i < 5; i++)
{
std::cout << foo() << std::endl;
}
return 0;
}```
<source>: In function 'float foo()':
<source>:8:10: error: 'uniform_float_distribution' is not a member of 'std'; did you mean 'uniform_real_distribution'?
8 | std::uniform_float_distribution<> distrib(0, 1);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
| uniform_real_distribution
<source>:8:37: error: expected primary-expression before '>' token
8 | std::uniform_float_distribution<> distrib(0, 1);
| ^
<source>:8:39: error: 'distrib' was not declared in this scope
8 | std::uniform_float_distribution<> distrib(0, 1);
| ^~~~~~~
Build failed
Because different values and random values ain’t the same
because of pseudorandomness or because it always has the same seed?
What
what did you than mean with that different values and random values are not the same?
If you always want different values just count up. If you want random values use a random number generator
In general you seed a PRNG once and then you simply reuse the seeded PRNG. The code that you first shared here reseeded it every time and thus causes issues with the generated sequence which might no longer be statistically be random
why would reseeding it every time cause it not to be random?
it's not uncommon for the first few numbers after seeding to be rather low quality for example
I am confused
about what exactly?
https://stackoverflow.com/questions/7320840/good-idea-to-seed-a-rng-each-time-you-use-it
This has a good example I think,
For instance, consider a PRNG which always returns the seed value itself as the first number in the sequence, but which is perfectly uniform over its range. This constitutes a great PRNG, as long as you don't use the first number. However, if you reseed it before every use, say to an incrementing counter value, you have no randomness at all!
and in most apps you are fine with initializing your mersenne twister once with one seed, and then you keep using that. You get enough good random numbers
If you want something secure you will need a true physical rng but at that point we probably wouldnt even have that discussion 😄
This question is being automatically marked as stale.
If your question has been answered, run !solved.
If your question is not answered feel free to bump the post or re-ask.
Take a look at !howto ask for tips on improving your question.
there seems to be a problem with the arguments I am putting in my tread but I can't figger out