Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
The problem with the following program is that the main thread ends before the other threads get a chance to display their results. Another issue is that the threads display isn't in order.
The output needs to be:
This is thread 0.
This is thread 1.
This is thread 2. etc.
code:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
void *text(void *arg);
long code[] = { 4, 6, 3, 1, 5, 0, 2 }; // Order in which to start threads
int num = 0;
int main()
{
int i;
pthread_t tid[7];
// Initialize random number generator
time_t seconds;
time(&seconds);
srand((unsigned int) seconds);
// Create our threads
for (i = 0; i < 7; i++)
pthread_create(&tid[i], NULL, text, (void*)code[i]);
// Exit main
return 0;
}
void *text(void *arg)
{
long n = (long)arg;
int rand_sec = rand() % (3 - 1 + 1) + 1; // Random num seconds to sleep
while (num != n) {} // Busy wait used to wait for our turn
num++; // Let next thread go
sleep(rand_sec); // Sleep for random amount of time
printf("This is thread %d.\n", n);
// Exit thread
pthread_exit(0);
}
Can anyone help with using a mutex to fix the synchronization problem?
You can use pthread_join to make your main routine wait until your other threads have finished, e.g.
int main()
{
int i;
pthread_t tid[7];
// Initialize random number generator
time_t seconds;
time(&seconds);
srand((unsigned int) seconds);
// Create our threads
for (i = 0; i < 7; i++)
pthread_create(&tid[i], NULL, text, (void*)code[i]);
for(i = 0; i < 7; i++)
pthread_join(tid[i], NULL);
// Exit main
return 0;
}
Also, your code which waits for num to be the thread ID might have some issues when you start turning optimisations on. Your num variable should be declared volatile if it is shared between threads, like so:
volatile int num;
That said, busy waiting on num like so is very, very inefficient. You should consider using condition variables to notify threads when num changes, so they can check if it is their turn once, then sleep if not. Have a look at all of the pthread_cond_* functions for more information.
Related
I am working with a large project and I am trying to create a test that does the following thing: first, create 5 threads. Each one of this threads will create 4 threads, which in turn each one creates 3 other threads. All this happens until 0 threads.
I have _ThreadInit() function used to create a thread:
status = _ThreadInit(mainThreadName, ThreadPriorityDefault, &pThread, FALSE);
where the 3rd parameter is the output(the thread created).
What am I trying to do is start from a number of threads that have to be created n = 5, the following way:
for(int i = 0; i < n; i++){
// here call the _ThreadInit method which creates a thread
}
I get stuck here. Please, someone help me understand how it should be done. Thanks^^
Building on Eugene Sh.'s comment, you could create a function that takes a parameter, which is the number of threads to create, that calls itself recursively.
Example using standard C threads:
#include <stdbool.h>
#include <stdio.h>
#include <threads.h>
int MyCoolThread(void *arg) {
int num = *((int*)arg); // cast void* to int* and dereference
printf("got %d\n", num);
if(num > 0) { // should we start any threads at all?
thrd_t pool[num];
int next_num = num - 1; // how many threads the started threads should start
for(int t = 0; t < num; ++t) { // loop and create threads
// Below, MyCoolThread creates a thread that executes MyCoolThread:
if(thrd_create(&pool[t], MyCoolThread, &next_num) != thrd_success) {
// We failed to create a thread, set `num` to the number of
// threads we actually created and break out.
num = t;
break;
}
}
int result;
for(int t = 0; t < num; ++t) { // join all the started threads
thrd_join(pool[t], &result);
}
}
return 0;
}
int main() {
int num = 5;
MyCoolThread(&num); // fire it up
}
Statistics from running:
1 thread got 5
5 threads got 4
20 threads got 3
60 threads got 2
120 threads got 1
120 threads got 0
I'm trying to count the number of prime numbers up to 10 million and I have to do it using multiple threads using Posix threads(so, that each thread computes a subset of 10 million). However, my code is not checking for the condition IsPrime. I'm thinking this is due to a race condition. If it is what can I do to ameliorate this issue?
I've tried using a global integer array with k elements but since k is not defined it won't let me declare that at the file scope.
I'm running my code using gcc -pthread:
/*
Program that spawns off "k" threads
k is read in at command line each thread will compute
a subset of the problem domain(check if the number is prime)
to compile: gcc -pthread lab5_part2.c -o lab5_part2
*/
#include <math.h>
#include <stdio.h>
#include <time.h>
#include <pthread.h>
#include <stdlib.h>
typedef int bool;
#define FALSE 0
#define TRUE 1
#define N 10000000 // 10 Million
int k; // global variable k willl hold the number of threads
int primeCount = 0; //it will hold the number of primes.
//returns whether num is prime
bool isPrime(long num) {
long limit = sqrt(num);
for(long i=2; i<=limit; i++) {
if(num % i == 0) {
return FALSE;
}
}
return TRUE;
}
//function to use with threads
void* getPrime(void* input){
//get the thread id
long id = (long) input;
printf("The thread id is: %ld \n", id);
//how many iterations each thread will have to do
int numOfIterations = N/k;
//check the last thread. to make sure is a whole number.
if(id == k-1){
numOfIterations = N - (numOfIterations * id);
}
long startingPoint = (id * numOfIterations);
long endPoint = (id + 1) * numOfIterations;
for(long i = startingPoint; i < endPoint; i +=2){
if(isPrime(i)){
primeCount ++;
}
}
//terminate calling thread.
pthread_exit(NULL);
}
int main(int argc, char** args) {
//get the num of threads from command line
k = atoi(args[1]);
//make sure is working
printf("Number of threads is: %d\n",k );
struct timespec start,end;
//start clock
clock_gettime(CLOCK_REALTIME,&start);
//create an array of threads to run
pthread_t* threads = malloc(k * sizeof(pthread_t));
for(int i = 0; i < k; i++){
pthread_create(&threads[i],NULL,getPrime,(void*)(long)i);
}
//wait for each thread to finish
int retval;
for(int i=0; i < k; i++){
int * result = NULL;
retval = pthread_join(threads[i],(void**)(&result));
}
//get the time time_spent
clock_gettime(CLOCK_REALTIME,&end);
double time_spent = (end.tv_sec - start.tv_sec) +
(end.tv_nsec - start.tv_nsec)/1000000000.0f;
printf("Time tasken: %f seconds\n", time_spent);
printf("%d primes found.\n", primeCount);
}
the current output I am getting: (using the 2 threads)
Number of threads is: 2
Time tasken: 0.038641 seconds
2 primes found.
The counter primeCount is modified by multiple threads, and therefore must be atomic. To fix this using the standard library (which is now supported by POSIX as well), you should #include <stdatomic.h>, declare primeCount as an atomic_int, and increment it with an atomic_fetch_add() or atomic_fetch_add_explicit().
Better yet, if you don’t care about the result until the end, each thread can store its own count in a separate variable, and the main thread can add all the counts together once the threads finish. You will need to create, in the main thread, an atomic counter per thread (so that updates don’t clobber other data in the same cache line), pass each thread a pointer to its output parameter, and then return the partial tally to the main thread through that pointer.
This looks like an exercise that you want to solve yourself, so I won’t write the code for you, but the approach to use would be to declare an array of counters like the array of thread IDs, and pass &counters[i] as the arg parameter of pthread_create() similarly to how you pass &threads[i]. Each thread would need its own counter. At the end of the thread procedure, you would write something like, atomic_store_explicit( (atomic_int*)arg, localTally, memory_order_relaxed );. This should be completely wait-free on all modern architectures.
You might also decide that it’s not worth going to that trouble to avoid a single atomic update per thread, declare primeCount as an atomic_int, and then atomic_fetch_add_explicit( &primeCount, localTally, memory_order_relaxed ); once before the thread procedure terminates.
I'm writing a toy program to help me understand how barriers work. In the program I have each thread checking to see if an element in one array is in another array. I was able to have all threads start searching simultaneously but I'd like to have them all meet up after filtering in order to correctly add any numbers to the array.
Without doing so, the the wrong numbers might be added to the array.
EDIT: Someone suggested I'd add pthread_barrier_wait(&after_filtering); in the call to filter_threads and that seemed to do trick. Now I know that I have to add a wait call in main as well as in the filter function, but I don't quite understand the flow of execution and how the wait calls in main work. I know that the wait in the thread function ensures that all threads reach that point before continuing but doesn't that happen as soon as the threads created? Meaning that nums should have values of 99 instead of 4, 3, 8, 1?
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
pthread_barrier_t before_filtering, after_filtering;
int nums[4] = {99, 99, 99, 99};
int arr[15] = {12, 5, 31, 8, 1, 6, 24, 4, 81, 42};
void filter(int i, int a[]){
// Loop through the list
int j;
for (j = 0; j < 10; j++)
{
if (nums[i] == a[j])
nums[i] = 0;
}
}
void *filter_threads(void *id){
int *myid = (int *)id;
printf("thread %d\n",*myid);
pthread_barrier_wait(&before_filtering);
filter(*myid, arr);
pthread_barrier_wait(&after_filtering);
}
int main(void)
{
pthread_t tids[3];
int index[3];
pthread_barrier_init(&before_filtering, NULL, 4);
pthread_barrier_init(&after_filtering, NULL, 4);
int i, j;
for (i = 0; i < 3; i++)
{
index[i] = i + 1;
pthread_create(&tids[i], NULL, filter_threads, &index[i]);
}
// Cannot call any filter function without first populating nums
nums[0] = 4;
nums[1] = 3;
nums[2] = 8;
nums[3] = 1;
pthread_barrier_wait(&before_filtering);
filter(0, arr);
pthread_barrier_wait(&after_filtering);
// Add new numbers to arr...
printf("New nums: ");
for (i = 0; i < 4; i++)
printf("%d, ", nums[i]);
printf("\n");
for (i = 0; i < 3; i++)
pthread_join(tids[i], NULL);
// Print new arr...
pthread_barrier_destroy(&before_filtering);
pthread_barrier_destroy(&after_filtering);
}
I tried adding another wait call after the filtering but now the program just hangs. How can I accomplish this?
A barrier is simply a mechanism to ensure that all N threads reach a certain point in the code before continuing. Hence, if you call pthread_barrier_init with a count of 4, any thread calling pthread_barrier_wait on that same barrier will not continue until three other threads have also called pthread_barrier_wait.
So, as your code provides now: the three created threads will, once started, execute the pthread_barrier_wait(&before_filtering) where they will all block until after the main thread has executed sleep(3) and then initialized the nums array. The main thread then calls pthread_barrier_wait(&before_filtering). This releases the main thread and all the others to continue execution.
After executing the filter function, each sub-thread and the main thread should execute pthread_barrier_wait(&after_filtering). Otherwise, the main thread will be stalled waiting for three other threads to wait on the barrier.
That being said, there is no need to use the second barrier at all. At that point, the main thread is really just waiting for the other three threads to finish their task and quit. The pthread_join on each sub-thread being done by the main thread accomplishes the same thing: i.e. the pthread_join on a thread will not return until that thread has finish execution.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I was creating a program to do some maths on some numbers for a school project. Say I have 10 threads but 42 items to process, I want them to process all the items evenly and take on an even amount of jobs. I'm using the POSIX pthread library, I know it's something to do with mutex but I'm not entirely sure.
Here's a simplified example of what I'm doing, however I want to balance the work load out evenly.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int numbers = { 1, 78, 19, 49, 14, 1, 14. 19, 57, 15, 95, 19, 591, 591 };
void* method() {
for(size_t i = 0; i < 14; i++) {
printf("%d\n", (numbers[i] * 2));
}
}
int main(int argc, char const *argv[]) {
pthread_t th[10];
for (size_t i = 0; i < 10; i++) {
pthread_create(&th[i], NULL, method, NULL);
}
return 0;
}
You want each thread to process given indices in the table. You don't have to protect the table with mutex as long as you divide work properly between threads so they won't race for the same data.
An idea:
/* this structure will wrap all thread's data */
struct work
{
size_t start, end;
pthread_t tid;
};
void* method(void*);
#define IDX_N 42 /* in this example */
int main(int argc, char const *argv[])
{
struct work w[10];
size_t idx_start, idx_end, idx_n = IDX_N / 10;
idx_start = 0;
idx_end = idx_start + idx_n;
for (size_t i = 0; i < 10; i++)
{
w[i].start = idx_start; /* starting index */
w[i].end = idx_end; /* ending index */
/* pass the information about starting and ending point for each
* thread by pointing it's argument to appropriate work struct */
pthread_create(&w[i], NULL, method, (void*)&work[i]);
idx_start = idx_end;
idx_end = (idx_end + idx_n < IDX_N ? idx_end + idx_n : IDX_N);
}
return 0;
}
void*
method(void* arg)
{
struct work *w = (struct work* arg);
/* now each thread can learn where it should start and stop
* by examining indices that were passed to it in argument */
for(size_t i = w->start; i < w->end; i++)
printf("%d\n", (numbers[i] * 2));
return NULL;
}
For a little bit more complex example you can check this and this.
If you know ahead of time (i.e., before starting the threads) how many items you need to process, you just need to partition them among the threads. For example, tell the first thread to process items 0-9, the next to process 10-19, or whatever.
I have two questions.
First:
I need to create thread blocks gradually not more then some max value, for example 20.
For example, first 20 thread go, job is finished, only then 20 second thread go, and so on in a loop.
Total number of jobs could be much larger then total number of threads (in our example 20), but total number of threads should not be bigger then our max value (in our example 20).
Second:
Could threads be added continuously? For example, 20 threads go, one thread job is finished, we see that total number of threads is 19 but our max value is 20, so we can create one more thread, and one more thread go :)
So we don't waste a time waiting another threads job to be done and our total threads number is not bigger then our some max value (20 in our example) - sounds cool.
Conclusion:
For total speed I consider the second variant would be much faster and better, and I would be very graceful if you help me with this, but also tell how to do the first variant.
Here is me code (it's not working properly and the result is strange - some_array elements become wrong after eleven step in a loop, something like this: Thread counter = 32748):
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <math.h>
#define num_threads 5 /* total max number of threads */
#define lines 17 /* total jobs to be done */
/* args for thread start function */
typedef struct {
int *words;
} args_struct;
/* thread start function */
void *thread_create(void *args) {
args_struct *actual_args = args;
printf("Thread counter = %d\n", *actual_args->words);
free(actual_args);
}
/* main function */
int main(int argc, char argv[]) {
float block;
int i = 0;
int j = 0;
int g;
int result_code;
int *ptr[num_threads];
int some_array[lines] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17};
pthread_t threads[num_threads];
/* counting how many block we need */
block = ceilf(lines / (double)num_threads);
printf("blocks= %f\n", block);
/* doing ech thread block continuously */
for (g = 1; g <= block; g++) {
//for (i; i < num_threads; ++i) { i < (num_threads * g),
printf("g = %d\n", g);
for (i; i < lines; ++i) {
printf("i= %d\n", i);
/* locate memory to args */
args_struct *args = malloc(sizeof *args);
args->words = &some_array[i];
if(pthread_create(&threads[i], NULL, thread_create, args)) {
free(args);
/* goto error_handler */
}
}
/* wait for each thread to complete */
for (j; j < lines; ++j) {
printf("j= %d\n", j);
result_code = pthread_join(threads[j], (void**)&(ptr[j]));
assert(0 == result_code);
}
}
return 0;
}