When I used brakpoints I saw that the variable idofprinter is 13 and maxPrintJobs is 10 but it still enters the while loop. why is that? Here is a part of my code and in the main I am using 4 different threads and joining these threads at the end of the main program
void user(const int &mintime, const int & maxtime, const int &userid)
{
while (idofprinter < maxPrintJobs) {
this_thread::sleep_for(chrono::seconds(random_range(mintime, maxtime))); // sleeps for a random amount of time
usermutex.lock();
usercounter++;
idofprinter++;
Related
I have a basic program that is using multi-threading. Each thread needs to use different random numbers when the thread procedure is called. I have tried seeding the random number generator within the thread procedure, but I get the same random numbers for each thread. Here is a simple version of what I am doing:
public ref class ThreadX
{
public:
void ThreadProc()
{
srand(time(NULL));
Console::WriteLine(rand()); //Will output same random numbers
}
}
int main(){
ThreadX^ process1 = gcnew ThreadX(gasStationATM);
Thread^ Thread1 = gcnew Thread(gcnew ThreadStart(process1, &ThreadX::ThreadProc));
Thread^ Thread2 = gcnew Thread(gcnew ThreadStart(process1, &ThreadX::ThreadProc));
Thread1->Start();
Thread2->Start();
}
What I originally thought was when the second thread was started, the second thread started the time for the seed would be different and give a different series of random numbers for the second number. How can I seed the srand in C++ CLI so that each thread generates random numbers.
When you create your Random instance, use the constructor that lets you specify a seed value. The default constructor uses the current system time as the seed value, so two instances created at the same time will use the same seed, and therefore produce the same sequence of random numbers.
For your seed value, there are two options for specifying different values: You could use some value unique to the thread you're running on, or you could use a unique number that you manage.
Random^ GetRandom1()
{
return gcnew Random(Thread::CurrentThread->ManagedThreadId);
}
static int uniqueID = 0;
Random^ GetRandom2()
{
return gcnew Random(Interlocked::Increment(uniqueID));
}
Another option is to use a single central RNG in your main thread. As each new thread is created, seed the thread's own RNG with the next number from the central RNG. This also has the advantage that you can repeat a run exactly if necessary by giving the central RNG a specific seed. That technique can be useful for repeating (and hence fixing) errors.
srand(time(NULL) + rank) will do the job.
At present, your seed is not thread specific. When all the threads are spawned, they have almost same time(NULL), and so value of seed is same for each thread. To avoid it, you can use rank of thread as seed, or any other thread specific variable.
I have to calculate the sum of the elements in a bidimensional matrix, using a separate thread to calculate the sum of each row. Then the main thread adds up these sums printing the final result.
Can you guys see what's wrong?
(I'm all new to the threads stuff)
#include <pthread.h>
#include <stdio.h>
void sumR(void* _a,int m,int n,int sum)
{
int i;
int (*a)[m]=_a;
for(i=1;i<=n;i++)
sum+=a[n][i];
}
int main()
{
int a[20][20],sum1,sum;
int m=3,n=3,k=3,i,j;
for(i=1;i<=m;i++)
{
k=k+3;
for(j=1;j<=n;j++)
a[i][j]=k;
}
sum1=0;
for(i=1;i<=m;i++)
{
sum=0;
pthread_t th;
pthread_create(&th,NULL,&sumR,&a,&m,&n,&sum);
sum1+=sum;
pthread_join(&th,NULL);
}
printf("Sum of the matrix is: %d",sum1);
return 0;
}
One problem I see is that your loop does essentially this:
for each row
start thread
add thread's sum to total
wait for thread to exit
That's not going to work because you're adding the thread's sum before the thread is done calculating it. You need to wait for the thread to finish:
start thread
wait for thread to exit
add thread's sum to total
However, that model doesn't take advantage of multiple threads. You only have one thread running at a time.
What you need to do is create all of the threads and store them in an array. Then wait for each thread to exit and add its sum to the total. Something like:
for i = 0 to num_threads-1
threads[i] = pthread_create(&threads[i], NULL, &sums[i], ...)
And then
for i = 0 to num_threads-1
pthread_join(&threads[i], ...);
sum += sums[i];
That way, all of your threads are running at the same time, and you harvest the result only when the thread is done.
I am trying to create a number of threads (representing persons), in a for loop, and display the person id, which is passed as an argument, together with the thread id. The person id is displayed as exepected, but the thread id is always the same.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void* travelers(void* arg) {
int* person_id = (int*) arg;
printf("\nPerson %d was created, TID = %d", *person_id, pthread_self());
}
int main(int argc, char** argv)
{
int i;
pthread_t th[1000];
for (i=0; i < 10; i++) {
if ((pthread_create(&th[i], NULL, travelers, &i)) != 0) {
perror("Could not create threads");
exit(2);
}
else {
// Join thread
pthread_join(th[i], NULL);
}
}
printf("\n");
return 0;
}
The output I get is something like this:
Person 0 was created, TID = 881035008
Person 1 was created, TID = 881035008
Person 2 was created, TID = 881035008
Person 3 was created, TID = 881035008
Person 4 was created, TID = 881035008
Person 5 was created, TID = 881035008
Person 6 was created, TID = 881035008
Person 7 was created, TID = 881035008
Person 8 was created, TID = 881035008
Person 9 was created, TID = 881035008
What am I doing wrong?
Since only one of the created threads runs at a time, every new one gets the same ID as the one that finished before, i.e. the IDs are simply reused. Try creating threads in a loop and then joining them in a second loop.
However, you will then have to take care that each thread independently reads the content of i, which will give you different headaches. I'd pass the index as context argument, and then cast it to an int inside the thread function.
It does that, because it re-uses thread-ids. The thread id is only unique among all running threads, but not for threads running at different times; look what your for-loop does essentially:
for (i = 0 to 10) {
start a thread;
wait for termination of the thread;
}
So the program has only one thread running at any given time, one thread is only started after the previous started thread has terminated (with pthread_join ()). To make them run at the same time, use two for loops:
for (i = 0 to 10) {
start thread i;
}
for (i = 0 to 10) {
wait until thread i is finished;
}
Then you will likely get different thread-ids. (I.e. you will get different thread-ids, but if the printf-function will write them out differently depends on your specific implementation/architecture, in particular if thread_t is essentially an int or not. It might be a long int, for example).
if ((pthread_create(&th[i], NULL, travelers, &i)) != 0)
If the thread is successfully created it returns 0. If != 0 will return false and you will execute the pthread_join. You are effectively creating one thread repeatedly.
using System.Threading.Tasks;
const int _Total = 1000000;
[ThreadStatic]
static long count = 0;
static void Main(string[] args)
{
Parallel.For(0, _Total, (i) =>
{
count++;
});
Console.WriteLine(count);
}
I get different result every time, can anybody help me and tell me why?
Most likely your "count" variable isn't atomic in any form, so you are getting concurrent modifications that aren't synchronized. Thus, the following sequence of events is possible:
Thread 1 reads "count"
Thread 2 reads "count"
Thread 1 stores value+1
Thread 2 stores value+1
Thus, the "for" loop has done 2 iterations, but the value has only increased by 1. As thread ordering is "random", so will be the result.
Things can get a lot worse, of course:
Thread 1 reads count
Thread 2 increases count 100 times
Thread 1 stores value+1
In that case, all those 100 increases done by thread 2 are undone. Although that can really only happen if the "++" is actually split into at least 2 machine instructions, so it can be interrupted in the middle of the operation. In the one-instruction case, you're only dealing with interleaved hardware threads.
It's a typical race condition scenario.
So, most likely, ThreadStatic is not working here. In this concrete sample use System.Threading.Interlocked:
void Main()
{
int total = 1000000;
int count = 0;
System.Threading.Tasks.Parallel.For(0, _Total, (i) =>
{
System.Threading.Interlocked.Increment(ref count);
});
Console.WriteLine(count);
}
Similar question
C# ThreadStatic + volatile members not working as expected
I'm optimizing some instrumentation for my project (Linux,ICC,pthreads), and would like some feedback on this technique to assign a unique index to a thread, so I can use it to index into an array of per-thread data.
The old technique uses a std::map based on pthread id, but I'd like to avoid locks and a map lookup if possible (it is creating a significant amount of overhead).
Here is my new technique:
static PerThreadInfo info[MAX_THREADS]; // shared, each index is per thread
// Allow each thread a unique sequential index, used for indexing into per
// thread data.
1:static size_t GetThreadIndex()
2:{
3: static size_t threadCount = 0;
4: __thread static size_t myThreadIndex = threadCount++;
5: return myThreadIndex;
6:}
later in the code:
// add some info per thread, so it can be aggregated globally
info[ GetThreadIndex() ] = MyNewInfo();
So:
1) It looks like line 4 could be a race condition if two threads where created at exactly the same time. If so - how can I avoid this (preferably without locks)? I can't see how an atomic increment would help here.
2) Is there a better way to create a per-thread index somehow? Maybe by pre-generating the TLS index on thread creation somehow?
1) An atomic increment would help here actually, as the possible race is two threads reading and assigning the same ID to themselves, so making sure the increment (read number, add 1, store number) happens atomically fixes that race condition. On Intel a "lock; inc" would do the trick, or whatever your platform offers (like InterlockedIncrement() for Windows for example).
2) Well, you could actually make the whole info thread-local ("__thread static PerThreadInfo info;"), provided your only aim is to be able to access the data per-thread easily and under a common name. If you actually want it to be a globally accessible array, then saving the index as you do using TLS is a very straightforward and efficient way to do this. You could also pre-compute the indexes and pass them along as arguments at thread creation, as Kromey noted in his post.
Why so averse to using locks? Solving race conditions is exactly what they're designed for...
In any rate, you can use the 4th argument in pthread_create() to pass an argument to your threads' start routine; in this way, you could use your master process to generate an incrementing counter as it launches the threads, and pass this counter into each thread as it is created, giving you your unique index for each thread.
I know you tagged this [pthreads], but you also mentioned the "old technique" of using std::map. This leads me to believe that you're programming in C++. In C++11 you have std::thread, and you can pass out unique indexes (id's) to your threads at thread creation time through an ordinary function parameter.
Below is an example HelloWorld that creates N threads, assigning each an index of 0 through N-1. Each thread does nothing but say "hi" and give it's index:
#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
inline void sub_print() {}
template <class A0, class ...Args>
void
sub_print(const A0& a0, const Args& ...args)
{
std::cout << a0;
sub_print(args...);
}
std::mutex&
cout_mut()
{
static std::mutex m;
return m;
}
template <class ...Args>
void
print(const Args& ...args)
{
std::lock_guard<std::mutex> _(cout_mut());
sub_print(args...);
}
void f(int id)
{
print("This is thread ", id, "\n");
}
int main()
{
const int N = 10;
std::vector<std::thread> threads;
for (int i = 0; i < N; ++i)
threads.push_back(std::thread(f, i));
for (auto i = threads.begin(), e = threads.end(); i != e; ++i)
i->join();
}
My output:
This is thread 0
This is thread 1
This is thread 4
This is thread 3
This is thread 5
This is thread 7
This is thread 6
This is thread 2
This is thread 9
This is thread 8