Calculating prime numbers using multi threading - c++

I started to work with threads recently and I tried to run a simple program that uses threads but I get really strange output.
The program writes the prime numbers in the given range with N(parameter to the function)number of threads into the file "PRIMES.txt", if the range <= 1000 the output is fine but if the range is bigger, then the output is something like :
‰‱′″‵‷ㄱㄠ″㜱ㄠ‹㌲㈠‹ㄳ㌠‷ㄴ㐠″㜴㔠″㤵㘠‱㜶㜠‱㌷㜠‹㌸㠠‹㜹ㄠ㄰ㄠ㌰ㄠ㜰ㄠ㤰ㄠ㌱ㄠ㜲ㄠㄳㄠ㜳ㄠ㤳ㄠ㤴ㄠㄵㄠ㜵ㄠ㌶ㄠ㜶ㄠ㌷ㄠ㤷... (much longer)
What would be the problem?
Here is my code :
threads.h :
#include <fstream>
#include <string>
#include <iostream>
#include <thread>
using namespace std;
void writePrimesToFile(int begin, int end, ofstream& file);
void callWritePrimesMultipleThreads(int begin, int end, string filePath, int N);
threads.cpp :
#include "Threads.h"
#include <iostream>
#include <string>
#include <fstream>
#include <thread>
#include <mutex>
#include <vector>
mutex mtx;
void PrimesToFile(int begin, int end, ofstream& file)
{
bool isPrime;
string Primes;
int count = 0;
mtx.lock();
cout << "Thread is running" << endl;
for (int i = begin; i < end; i++)
{
isPrime = true;
for (int j = 2; j < i; j++)
{
if (i%j == 0)
isPrime = false;
}
if (isPrime)
{
Primes.append(to_string(i));
Primes.append(" ");
}
}
file.write(Primes.c_str(), Primes.length());
mtx.unlock();
}
void WritePrimesMultipleThreads(int begin, int end, string filePath, int N)
{
ofstream OP;
OP.open(filePath);
int lastPos = 0;
int destPos = end / N;
thread* TV = new thread[N];
for (int i = 0; i < N; i++)
{
TV[i] = thread(PrimesToFile, lastPos, destPos, ref(OP));
lastPos = destPos;
destPos += end / N;
}
for (int i = 0; i < N; i++)
TV[i].join();
}
Starting point :
#include "Threads.h"
#include <iostream>
#include <string>
#include <fstream>
#include <thread>
void main()
{
WritePrimesMultipleThreads(1, 10000, "PRIMES.txt", 5);
system("PAUSE");
}
Thanks!

Hours of debugging turned out to be in wrong implementation of std::ofstream. Just outputting at the beginning OP << "\n" solved the problem. Compiler is MSVC 2015 update 1. More about about it here. Additionally, you have resource leak, single threading when it is not really intended to, not efficient algorithm of finding primes in a range, compiling errors in your posted code, unnecessary writePrimesToFile function and header files in your header file, you're using using namespace std and may be more problems. I recommend you posting your code at codereview.stackexchange.com to make the code better, because solving this problem is not enough to solve the original problem.
EDIT: You need to flush the stream every time you done writing something.

Related

how to return a value without exiting a function and storing it subsequently, in c++

Here I'm trying to mimic data feed streaming from stock exchange using random number and subsequently store it in array.
#include <iostream>
#include <array>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <vector>
#include <fstream>
#include <cstdlib>
#include <chrono>
#include <ctime>
#include <stdlib.h>
long int prevcntr=0;
using namespace std;
std::pair<long int, double>feedgenerator(long int len)
{
srand(time(0));
for(long int itr=1;itr<=len;itr++)
{
return {itr, (double)rand()/RAND_MAX};
//should continue evaluating the function without exiting
pause(0.001); //To allow some interval for 'makearray' to store it
}
}
template<size_t nn>
std::array<double, nn> makearray(long int cntr, double value, long int len)
{
std::array<double, nn> outarr; // should be able to pass the value of 'len' to 'nn'
long int itr=0;
begin:
while(cntr <= prevcntr)goto begin; // should wait until the next update
outarr[itr] = value;
prevcntr = cntr;
while(itr<len)
{
itr++;
goto begin; // control goes back to the beginning until all the elements of the array are filled with value
}
//should return the array after it is fully filled
return outarr;
}
int main()
{
double *p=new double[];
long int len = 100000;
*p = makearray(feedgenerator(len), len)
// I should be able to call these as nested functions as above
for(int i=0;i<len;i++)
cout<<*p[i]<<"\n";
return 0;
}
Question is how do I return a value without exiting the feedgenerator function. If I try to get all the values at once then it wouldn't mimic the data feed. Data feed is essentially, the same value being updated, sequentially.
To store the data, makearray is being used (vector shouldn't be used as it is extremely slow).
Overall the idea is, feedgenerator should update the same value with an increasing counter (in the real scenario counter will be the time and value will be price etc.) and makearray should store the data (Unless I store the data, the data would be lost, as in the case of data feed from stock exchange) for subsequent analysis.
In makearray, I want to pass the length of the array as an argument of the function, so that it can be controlled by another program. How can it be done is not clear to me.
The code in it's present form, doesn't compile.
Question is how do I return a value without exiting the feedgenerator function
Because you are trying to mimic the data feed stream from stock exchange, so, I think you should consider to use thread. Example:
#include <unistd.h>
#include <deque>
#include <vector>
#include <algorithm>
#include <mutex>
#include <thread>
#include <iostream>
class FeedGenerator {
long int max_length;
std::deque<double> queue;
std::mutex mutex;
std::thread thread;
bool stop;
public:
FeedGenerator(long int len) :
max_length(len), stop(false),
thread(&FeedGenerator::run, this) {
}
virtual ~FeedGenerator() {
stop = true;
thread.join();
}
// Get the latest `len` values
int getData(std::vector<double>& vec, int len) {
std::lock_guard<std::mutex> lock(mutex);
if (queue.empty()) return 0;
int nlen = std::min((size_t)len, queue.size());
vec.resize(nlen);
std::copy(queue.end() - nlen, queue.end(), vec.begin());
return nlen;
}
private:
void run() {
srand(time(0));
while (!stop)
{
{
std::lock_guard<std::mutex> lock(mutex);
queue.push_back((double)rand()/RAND_MAX);
if (queue.size() >= max_length) {
queue.pop_front();
}
}
usleep(1000);
}
}
};
int main()
{
long int len = 100000;
FeedGenerator feedgenerator(len);
sleep(1);
std::vector<double> p;
feedgenerator.getData(p, 10); // get the latest 10 values
for(int i=0;i<p.size();i++)
std::cout << p[i] << std::endl;
return 0;
}

C++ alternative to singleton design when a function-only class needs to be initialize at least once?

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <random>
#include <map>
#include <math.h>
#include <cstring>
using namespace std;
class MathClass {
private:
size_t current_capacity;
double* logfact;
bool inited = false;
MathClass() {
current_capacity = 0;
logfact = new double[1];
logfact[0] = 0;
}
void calculateLogFact(int n) {
if (current_capacity >= n) return;
double* newLogfact = new double[n+1];
for (int i=0; i<=current_capacity; i++) newLogfact[i] = logfact[i];
for (int i=current_capacity+1; i<=n; i++) newLogfact[i] = newLogfact[i-1] + log(double(i));
delete[] logfact;
logfact = newLogfact;
}
double factorial(int n) {
cout << "n = " << n << "\n";
calculateLogFact(n);
for (int i=0; i<=n; i++) cout << int64_t(round(exp(logfact[i]))) << " ";
cout << "\n";
return exp(logfact[n]);
}
public:
static double factorial2n(int n) {
static MathClass singleton;
return singleton.factorial(2*n);
}
};
int main(int argc, char** argv)
{
cout << MathClass::factorial2n(10) << "\n";
return 0;
}
My library need to use an expensive function that needs to be initialized once before use (to pre-calculate some expensive values so that we don't have to calculate them every time). Currently, I use the singleton method above for this.
However, there are 2 problems:
Multi-threading: this will cause race conditions if 2 different threads call this function.
People don't like singleton
Other problems that I'm not aware of
What other design can I use to solve this problem? Pre-computing values is a must since this function needs to be fast.
I agree with comments: Why hide the fact that MathClass caches results from the user? I, as a potential user, see no real benefit, rather potential confusion. If I want to reuse previously cached results stored in an instance I can do that. You need not wrap the whole class in a singleton for me to enable that. Also there is no need to manually manage a dynamic array when you can use std::vector.
In short: The alternative to using a singleton is to not use a singleton.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <random>
#include <map>
#include <math.h>
#include <cstring>
using namespace std;
class MathClass {
private:
size_t current_capacity;
std::vector<double> logfact;
bool inited = false;
void calculateLogFact(int n) {
if (logfact.size() >= n) return;
auto old_size= logfact.size();
logfact.resize(n);
for (int i=old_size; i<n; i++) logfact.push_back(logfact.back() + log(double(i)));
}
double factorial(int n) {
cout << "n = " << n << "\n";
calculateLogFact(n);
for (int i=0; i<=n; i++) cout << int64_t(round(exp(logfact[i]))) << " ";
cout << "\n";
return exp(logfact[n]);
}
public:
MathClass() {
logfact.push_back(0);
}
double factorial2n(int n) {
return factorial(2*n);
}
};
void foo(MathClass& mc) { // some function using previously calculated results
std::cout << mc.factorial2n(2);
}
int main(int argc, char** argv)
{
MathClass mc;
cout << mc.factorial2n(10) << "\n";
foo(mc);
}
I am not sure if the maths is correct, I didn't bother to check. Also inited and most of the includes seem to be unused.
Concerning "Multi-threading: this will cause race conditions if 2 different threads call this function." I would also not bother too much to bake the thread-safety into the type itself. When I want to use it single-threaded I do not need thread-safety, and I don't want to pay for it. When I want to use it multi-threaded, I can do that by using my own std::mutex to protect access to the mc instance.
PS: Frankly, I think the whole issue is caused by a misconception. Your MathClass is not a "function only" class. It is a class with state and member functions, just like any other class too. The "misconception" is to hide the state from the user and pretend that there is no state when in fact there is state. When using this class I would want to be in conctrol what results I can query because they are already cached and which results need to be computed first. In other words, I would provide more access to the class state, rather than less.

Check the presence of a number in an array with binary search

I have a test assessment that I need to do. There is one question that I have been having trouble with.
I have an array of numbers and I need to find a way to find that number in the array, which I have partially done. The problem becomes in the next step of the project which is that it has to accommodate a million items.
I believe this is binary search. How do I do a binary search or equivalent?
#include <iostream>
#include <sys/resource.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <algorithm>
#include <vector>
using namespace std;
class Answer
{
public:
static bool exists(int ints[], int size, int k)
{
for(int i=0; i<size; i++){
if(ints[i]<k){
return true;
}
}
return false;
}
};
The images below gives an idea of what I need and my code
What I need:
Why don't you just use standart lib function?
static bool exists(int ints[], int size, int k)
{
return std::binary_search(ints, ints + size, k);
}
I have already seen you got the answer, but it's never bad to implement binary search yourself, especially on the algorithm course, so may be it will help you to understand the algorithm:
static bool exists(const int ints[], int size, int k) {
int left = 0, right = size-1;
while(right-left>1) {
int middle = (right+left)/2;
if(ints[middle] > k) right = middle;
else left = middle;
}
if(ints[right] == k || ints[left] == k) return true;
return false;
}

C++:Error: unable to create variable object at stl_list.h

I have this:
My includes
#include<iostream>
#include <list>
#include <fstream>
#include <vector>
#include <sstream>
using namespace std;
Where it crashes:
for (i = 0; i < j; i++){
Actual = SPLITaVecINT(txtvec[i+1]);
max = Actual.size();
if (max != 1) {
for (k = 0; k < porte; k++) {
Grf.addEdge(Actual[0], Actual[k+1]); //**HERE IT CRASHES**
}
}
}
Grf.bridge();
addEdge is here, its using double-linked lists.
void Graph::addEdge(int v, int w)
{
adj[v].push_back(w);
adj[w].push_back(v); // Note: the graph is undirected
}
So while debugging in CLion, it goes to stl_lib.h at line 1799 saying next to it "__position: 0 __args#0: var-create: unable to create var object" while highlighting line 1801.
Can't see where is the error in my code. Help please.

Code Crashes Immediately After Running

Even at the bare minimum of 10 numbers to input, I get no errors but my code crashes immediately on running. I was also wondering, what should I do if I have a question similar to another question that I've already asked, but on another new problem?
#include <iostream>
#include <cmath>
#include <fstream>
#include <cstdlib>
#include <vector>
using namespace std;
int primer(int max);
int main()
{
primer(5);
system("pause");
return 0;
}
int primer(int max){
vector<int> a;
a[1]=2;
for (int i=2;i<=max;i++){
bool prime=true;
for (int ii=0;ii<a.size();ii++) {
if (i/a[ii]==floor(i/a[ii])) {
prime=false;
}
}
if (prime==true) {
a.push_back(i);
}
}
for (int iii=0;iii<=a.size();iii++) {
cout << a[iii] << endl;
}
}
I get no errors but the compiled code crashes immediately.
I changed it to
#include <iostream>
#include <cmath>
#include <fstream>
#include <cstdlib>
#include <vector>
using namespace std;
int primer(int max);
int main()
{
primer(5);
system("pause");
return 0;
}
int primer(int max){
vector<int> a;
a.push_back(2);
for (double i=2;i<=max;i++){
bool prime=true;
for (int ii=0;ii<a.size();ii++) {
if (i/a[ii]==floor(i/a[ii])) {
prime=false;
}
}
if (prime) {
a.push_back(i);
}
}
for (int iii=0;iii<=a.size();iii++) {
cout << a[iii] << endl;
return a.size();
}
}
I addressed all of your problems. It still returns no errors and still crashes.
What makes you think you can do this?
vector<int> a;
a[1]=2;
vector<int> a;
a[1]=2;
You can't access a[1] until you've reserved space for it. You should probably use a.push_back(2) to append 2 to the end of a.
You have declared primer to return int, yet it returns nothing. Either make it void or return the number of primes.
i/a[ii]==floor(i/a[ii]) isn't going to do what you expect. i/a[ii] performs integer division. You should cast i to double before dividing.
if (prime==true) can be changed to simply if (prime), no need to compare a boolean to true.
Please improve your coding style. Use proper indentation and more commonly used variable names: i, j, k instead of i, ii, iii.
Here is another bug:
for (int iii=0;iii<=a.size();iii++) {
cout << a[iii] << endl;
return a.size();
}
My understanding is that you can only return once from a function, main included. The execution will not loop here because of the return statement.
Did you really want a return statement inside a for loop?