#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <pthread.h>
int ids = 0;
sem_t sync;
int idx = 0;
int count = 0;
void * add2(void * p_idx) {
int * tmp = (int *) p_idx;
int id = ids++;
sem_wait(&sync);
(*tmp)++;
count++;
printf("executed by %d, number is %d\n", id, *tmp);
sem_post(&sync);
}
int createThreadOutsideMain() {
pthread_t *outsideMain = malloc(sizeof(pthread_t));
pthread_create(outsideMain, NULL, add2, (void *) &idx);
pthread_join(*outsideMain, NULL);
return 0;
}
void * add(void * p_idx) {
int * tmp = (int *) p_idx;
int id = ids++;
while(count < 10) {
if (count % 2 == 0) {
continue;
}
sem_wait(&sync);
(*tmp)++;
count++;
printf("executed by %d, number is %d\n", id, *tmp);
sem_post(&sync);
}
createThreadOutsideMain();
}
int main(int argc, char * argv[]) {
pthread_t insideMain1, insideMain2;
sem_init(&sync, 0, 1);
pthread_create(&insideMain1, NULL, add, (void *) &idx);
pthread_create(&insideMain2, NULL, add, (void *) &idx);
pthread_join(insideMain1, NULL);
pthread_join(insideMain2, NULL);
return 0;
}
I am a newer to C and pthread libary, I ran into a situation. Generally describled as below.
I want to create threads and join the thread outside main function during runtime according to the input, so here I use an if statemnt to create a new
thread if count is odd number.
i want all the threads using the same semaphore &sync, but when I run the code, it just stuck,
i want to the output like this
executed by 0, number is 0
executed by 1, number is 1
executed by 2, number is 2
executed by 3, number is 3
executed by 0, number is 4
executed by 4, number is 5
executed by 2, number is 6
executed by 0, number is 7
...
is this idea possible? if so, where is my problem, thanks for your help!
First fix the below while loop and try again. This loop will indefinite as condition in if will always true. The reason is, while you are calling the add method from the first thread you are passing the parameter with zero. First it lock the mutex and stuck in the while loop for ever and your second thread is waiting for the lock to be unlock. Hence your application is finally stuck in the loop for ever. Pass the parameter as 1 and check what happened.
while(count < 10) {
if (count % 2 == 0) {// value of (0 % 2) == 0 always and this loop will continue for ever
continue;
}
if (count % 2 == 0) {
continue;
}
replace above code with this because if if statement is true count value is not changing and continue statement is taking to infinite loop
if (count % 2 == 0) {
count++;
continue;
}
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
Problem Statement: To detect whether a long integer number is a prime or not.
My Logic:
The idea is to iterate from 0 to sqrt(n). If no divisor was found between 0 to sqrt(n) then I can conclude that the number is prime and a non-prime otherwise.
Since, this needs to be multi-threaded I created a thread function called void* PrimeDetecter(void* param);. In this thread function I will iterate from startIndex to endIndex and if there was a divisor then quit the thread and write the value 1 to state true to the address of the variable isNum1Prime which is set to 0 by default.
Therefore, in the main function I need to send the number which will be checked, its start index and end index to the thread when creating the thread. So my structure will contain long int number, startIndex, endIndex, *divisor and int isPrime.
Then I create an array of size 10 of type NumberPrime because there are 10 threads and hence divide the iteration equally.
I printed the distribution of index among the threads and that works fine. Then I just create the threads and send all these elements to the thread to check whether the number is prime or not.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <math.h>
#include <pthread.h>
#define MAX_NUM_THREADS 10 // Exercise 1: Not more than 10 threads can run at a time for example.
struct NumberPrime
{
long int number, startIndex, endIndex, *divisor;
int *isPrime;
};
void *PrimeDetector(void *param)
{
struct NumberPrime parameters = *(struct NumberPrime *)param;
for (long int i = parameters.startIndex; i < parameters.endIndex; i++)
{
if (i == 0 || i == 1)
{
break;
}
else
{
if ((parameters.number % i) == 0) // if the divisor is detected then number is not a prime
{
*(parameters.divisor) = i;
*(parameters.isPrime) = 1; // change the value to true
pthread_exit(0); // exit the thread function
}
}
}
}
int main(int argc, char *argv[])
{
long int number1 = 12340000, number2 = 128;
struct NumberPrime primeData1[MAX_NUM_THREADS];
int isNum1Prime = 0; // false
long int number1Divisor = 0;
long int numberSquareRoot1 = (long int)(sqrt(number1)); // get the square root of number1
for (int i = 0; i < MAX_NUM_THREADS; i++)
{
primeData1[i].number = number1;
primeData1[i].isPrime = &isNum1Prime;
primeData1[i].divisor = &number1Divisor;
primeData1[i].startIndex = i * numberSquareRoot1 / MAX_NUM_THREADS;
primeData1[i].endIndex = ((i + 1) * numberSquareRoot1) / MAX_NUM_THREADS;
}
pthread_t primeDetectorThread1[MAX_NUM_THREADS];
int count = 0;
for (int i = 0; i < MAX_NUM_THREADS; i++)
{
if (isNum1Prime == 1)
{
pthread_cancel(primeDetectorThread1[i]);
break;
}
else
{
pthread_create(&primeDetectorThread1[i], NULL, &PrimeDetector, &primeData1[i]);
count++;
}
}
for (int i = 0; i < count; i++)
{
pthread_join(primeDetectorThread1[i], NULL);
}
isNum1Prime == 1 ? printf("Number 1 is prime.\n") : printf("Number 1 is not prime and divisible by %ld\n", number1Divisor);
return EXIT_SUCCESS;
}
The expected output is that the number is not a prime. But no matter what number I choose I always get that the number is prime.
The line if ((parameters.number % i) == 0) tests whether a number is divisible by i. If it is divisible, the number is not prime, but your code goes on to set *(parameters.isPrime) = 1; and end the thread.
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 7 years ago.
Improve this question
As a programming exercise I tried to write a program which exploited threads in order to have a faster computation of whether a number is prime or not.
My idea was to subdivide the number in P intervals where P is passed as a parameter on the command line, then evaluate an interval inside each thread.
The problem here is that I have to evaluate every odd number inside the interval and this takes a lot of time to do.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
int prime = 1; // flag for detecting non-prime numbers
// numbers are prime until a divisor is found
struct args {
long long start; // start of the subset of the interval
long long end; // end of the subset of the interval
long long N; // input number
};
void * runner (void *arg);
struct args * allocate_struct ( int P );
pthread_t * allocate_tids ( int P );
int
main (int argc, char *argv[])
{
int P; // number of threads
long long N; // number to check
pthread_t *tids;
struct args *args_array;
long long q; // quotient
int i;
if (argc != 3)
{
fprintf (stderr, "Wrong number of arguments\n");
printf ("Correct usage: %s <input number> <number of threads to use>\n", argv[0]);
exit(1);
}
N = atol(argv[1]); // fetch the input number
if (N <=0)
{
fprintf (stderr, "The input number must be positive\n");
exit(1);
}
P = atoi(argv[2]); //fetch the number of threads
if (P <=0)
{
fprintf (stderr, "The number of threads must be positive\n");
exit(1);
}
if (P > N)
{
fprintf (stderr, "The number of threads must be smaller than the input number\n");
exit(1);
}
q = (N/2)/(long long)P; // find the width of the intervals
args_array = allocate_struct ( P );
tids = allocate_tids ( P );
/* the following instructions are used to define the sub-intervals among the P threads */
args_array[0].start = 2;
args_array[0].end = args_array[0].start+q;
args_array[0].N = N;
for (i = 1; i < P; i += 1)
{
args_array[i].start = args_array[i-1].end+1;
args_array[i].end = args_array[i].start+q;
args_array[i].N = N;
}
/* threads are created and start running */
for (i = 0; i < P; i += 1)
{
if (pthread_create(&tids[i], NULL, runner, (void *) &args_array[i]))
{
fprintf (stderr, "Error during creation of a thread\n");
exit(1);
}
}
/* the main thread waits the end of the runner threads */
for (i = 0; i < P; i += 1)
{
pthread_join(tids[i], NULL);
}
if (prime == 1)
{
printf("The number is prime.\n");
} else {
printf ("The number isn't prime.\n");
}
return 0;
}
void * runner (void * arg) {
struct args * args;
long long i;
args = (struct args *) arg;
for (i = args->start; i < args->end && prime != 0; i += 1) //
{
if ((args->N % i) == 0 && (args->N != i))
{
prime = 0;
printf("%lld is a divisor\n", i);
pthread_exit(NULL);
}
}
pthread_exit(NULL);
}
pthread_t * allocate_tids ( int P ){
pthread_t *np_t;
np_t = (pthread_t *) malloc (sizeof (pthread_t ) * P);
if (np_t == NULL)
{
fprintf (stderr, "Error in allocation\n");
exit(1);
}
return np_t;
}
struct args * allocate_struct ( int P ) {
struct args *np_s;
np_s = (struct args *) malloc (sizeof (struct args) * P);
if (np_s == NULL)
{
fprintf (stderr, "Error in allocation\n");
exit(1);
}
return np_s;
}
As I said, the result was pretty poor. I went back to a single thread idea and came up with the following:
#include <stdlib.h>
#include <stdio.h>
int main (int argc, char ** argv) {
long long number;
long long i;
int prime = 1;
number = atol(argv[1]);
if (number < 1) {
printf("The number must be positive.\n");
exit(1);
}
if (number == 2)
{
prime = 1;
i = 2;
}
else if (number == 3)
{
i = 3;
prime = 1;
}
else if (number % 2 == 0)
{
i = 2;
prime = 0;
}
else
{
for ( i = 3; i <= number/i; i+=2 ) {
if (number%i == 0) {
prime = 0;
break;
}
}
}
if (prime) {
printf("The number %lld is prime.\n", number);
} else {
printf("The number %lld is not prime, its first divisor is %lld\n", number, i);
}
printf("Loop ended at iteration %lld\n", i);
return 0;
}
After fixing all the issues there were in the first program, it works and takes about 10 seconds with 1 thread/5 seconds with 4 to check the same number as the one below (which takes tens of milliseconds).
As a curiosity, can I further improve the second solution? How?
Also, I am not that experienced with threads so I probably made mistakes in both creation and usage, please do point them out.
If you check whether a number is prime or not, you most often find out very quickly that it is composite because it has a small divisor. All but 48/210ths of all integers are divisible by 2, 3, 5 or 7. So for good results you would have to find a way to stop all these threads from wasting CPU time once the first thread has (often very quickly) found a divisor.
Alternatively, you can test for example all divisors up to sqrt (x) / 5 first, then decide that it's unlikely that there is a divisor, and divide the rest of the range into four threads. Estimating your chances of finding a divisor and estimating how much time is wasted would be a nice interesting maths problem.
In reality, you will likely want to check many numbers for primality, and you can easily let one thread check one number. Much, much easier to do efficiently.
Sequential version stops at first divisor, but threaded version not. Only the thread finding the divisor exits early, the rest go on until they find another divisor [or not]. The thread finding the first divisor should cancel other (pthread_cancel) to finish.
Negative numbers are not prime by definition. Also, 2 is the only even prime. Hence you can pre-check a great many numbers simply:
if (number <= 1) {
return false; // False means not prime.
}
if (number % 2 == 0) {
return number == 2; // 2 is the only even prime.
}
// Check for factors of 3, 5, etc.
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;
}
The task is to have 5 threads present at the same time, and the user assigns each a burst time. Then a round robin algorithm with a quantum of 2 is used to schedule the threads. For example, if I run the program with
$ ./m 1 2 3 4 5
The output should be
A 1
B 2
C 2
D 2
E 2
C 1
D 2
E 2
E 1
But for now my output shows only
A 1
B 2
C 2
Since the program errs where one thread does not end for the time being, I think the problem is that this thread cannot unlock to let the next thread grab the lock. My sleep() does not work, either. But I have no idea how to modify my code in order to fix them. My code is as follows:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
double times[5];
char process[] = {'A', 'B', 'C', 'D', 'E'};
int turn = 0;
void StartNext(int tid) //choose the next thread to run
{
int i;
for(i = (tid + 1) % 5; times[i] == 0; i = (i + 1) % 5)
if(i == tid) //if every thread has finished
return;
turn = i;
}
void *Run(void *tid) //the thread function
{
int i = (int)tid;
while(times[i] != 0)
{
while(turn != i); //busy waiting till it is its turn
if(times[i] > 2)
{
printf("%c 2\n", process[i]);
sleep(2); //sleep is to simulate the actual running time
times[i] -= 2;
}
else if(times[i] > 0 && times[i] <= 2) //this thread will have finished after this turn
{
printf("%c %lf\n", process[i], times[i]);
sleep(times[i]);
times[i] = 0;
}
StartNext(i); //choose the next thread to run
}
pthread_exit(0);
}
int main(int argc, char **argv)
{
pthread_t threads[5];
int i, status;
if(argc == 6)
{
for(i = 0; i < 5; i++)
times[i] = atof(argv[i + 1]); //input the burst time of each thread
for(i = 0; i < 5; i++)
{
status = pthread_create(&threads[i], NULL, Run, (void *)i); //Create threads
if(status != 0)
{
printf("While creating thread %d, pthread_create returned error code %d\n", i, status);
exit(-1);
}
pthread_join(threads[i], 0); //Join threads
}
}
return 0;
}
The program is directly runnable. Could anyone help me figure it out? Thanks!
Some things I've figured out reading your code:
1. At the beginning of the Run function, you convert tid (which is a pointer to void) directly to int. Shouldn't you dereference it?
It is better to make int turn volatile, so that the compiler won't make any assumptions about its value not changing.
When you call the function sleep the second time, you pass a parameter that has type double (times[i]), and you should pass an unsigned int parameter. A direct cast like (unsigned int) times[i] should solve that.
You're doing the pthread_join before creating the other threads. When you create thread 3, and it enters its busy waiting state, the other threads won't be created. Try putting the joins after the for block.