Here is a block of code that creates a number of threads provided by the user, each thread then generates a random number and calculates its squareroot. I cannot figure out why the threads are getting the same ID, line 64 is the culprit as it is where the threads are being created. I suspect that there is something happening in the loop that is causing the threads to all be generated at the same time.
////////////////////////////////////////////////
//
//
// Zach
//
//
//
//
////////////////////////////////////////////////
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <math.h>
void *squareroot(void *num1)
{
int *id = (int *)num1;
int incoming = rand()/100;
float *outgoing = (float *)malloc(sizeof(float));
printf("%d \n", *id);
printf("%d\n", incoming);
*outgoing = 5.000;
//Calculate the square root of the number passed to the function
*outgoing = sqrt(incoming);
return outgoing;
}
int main(int argc, char* argv[])//testing funcion
{
srand(time(NULL));
int i, j;
int *temp = (int *)malloc(sizeof(int));
if (argc != 2)
{
printf ("ERROR: Enter a number\n");
return 1;
}
int loop = atoi(argv[1]); //grabbing the integer supplied by user
pthread_t thread_id[loop];
void *exit_status;
float *thread_result;
for(i = 0; i < loop; i++)
{
pthread_create(&thread_id[i], NULL, squareroot, &i);
}
for(j = 0; j < loop; j++)
{
pthread_join(thread_id[j], &exit_status);
thread_result = (float *)exit_status;
printf("%f\n", *thread_result);
}
}
I think what is happening is that your loop finishes creating all the threads (or at least some of them) before any of the threads actually run and extract their unique id.
Because you're passing a pointer to i, when each thread finally gets around to checking its parameter, i is already finished... Or at least partway through. The danger is that multiple threads might see the same value for i. It's even worse that you never copy the value out of that pointer - you always dereference it. That means it might change in the middle of your thread's execution.
What you should do instead is pretend it is a pointer:
pthread_create(&thread_id[i], NULL, squareroot, (void*)i);
And in your thread function:
int id = (int)num1;
This works because the pointer is passed by value. Whatever value you provide is the value that goes into the thread function. Previously it didn't work because you passed a pointer to a value that could change in another thread.
PS: Don't forget to free the result from each thread in your loop at the end. At the moment you're not cleaning up memory that you allocated.
Related
I am trying to use the WaitOnAddress() function to achieve read-write synchronization.
According to MSDN, WaitOnAddress() has the following declaration:
BOOL WaitOnAddress(
volatile VOID *Address,
PVOID CompareAddress,
SIZE_T AddressSize,
DWORD dwMilliseconds
);
and the following parameter definition:
CompareAddress
A pointer to the location of the previously observed value at Address. The function returns when the value at Address differs from the value at CompareAddress.
According to the definition, I should store and pass the current value of the watched address, so when the watch value changes, WaitOnAddress() will return. But this function does not work as I expected, so I wrote the following test code for WaitOnAddress() in Visual Studio (and also included linker library Synchronization.lib):
#include <stdio.h>
#include <stdlib.h> // atoi
#include <string.h>
// include these two files after including winsock2.h
#include <process.h>
#include <Windows.h>
#include <synchapi.h>
void* threads(void* num) {
int* number = (int*)num;
for (int i = 0; i < 10; i++) {
printf("number = %d\n", *number);
}
int catch = *number; // will be passed as CompareAddress
WaitOnAddress((int*)num, &catch, sizeof(int), INFINITE);
for (int i = 0; i < 10; i++) {
printf("number2 = %d, %d\n", catch, *(int*)num);
}
return NULL;
}
int main() {
int int_list[10];
for (int i = 0; i < 10; i++) {
int_list[i] = i;
_beginthread(threads, 0, (void*)&int_list[i]);
}
printf("hello\n");
Sleep(1000);
for (int i = 0; i < 10; i++) {
int_list[i] = 10 - i;
}
printf("changed\n");
Sleep(1000);
return 0;
}
In above code, WaitOnAddress() never returns even though the value it watches changes. But, if I change
int catch = *number;
to:
int catch = 10 - *number;
then WaitOnAddress() returns and the rest of the output is printed, as if it returns ONLY when the watched value matches the compared value.
But, I want to used the described behavior so my thread is released whenever the watched variable is changed.
According to the documentation:
Parameters
Address
The address on which to wait. If the value at Address differs from the
value at CompareAddress, the function returns immediately. If the
values are the same, the function does not return until another thread
in the same process signals that the value at Address has changed by
calling WakeByAddressSingle or WakeByAddressAll or the timeout
elapses, whichever comes first.
Although you modify the value of the original array in the second loop, the catch and num are always the same when calling WaitOnAddress in the thread, so the WaitOnAddress function will not return.
You can try to modify it to:
#include <stdio.h>
#include <stdlib.h> // atoi
#include <string.h>
// include these two files after including winsock2.h
#include <process.h>
#include <Windows.h>
void* threads(void* num) {
int* number = (int*)num;
printf("number = %d\n", *number);
int catch = *number; // will be passed as CompareAddress
WaitOnAddress((int*)num, &catch, sizeof(int), INFINITE);
printf("number2 = %d, %d\n", catch, *(int*)num);
return NULL;
}
int main() {
int int_list[10];
for (int i = 0; i < 10; i++) {
int_list[i] = i;
_beginthread(threads, 0, (void*)&int_list[i]);
}
printf("hello\n");
Sleep(1000);
printf("changed\n");
for (int i = 0; i < 10; i++) {
int_list[i] = 10 - i;
WakeByAddressSingle(&int_list[i]);
}
Sleep(1000);
return 0;
}
And it works for me:
I just started at college to study a little bit about threads, and it seems that I don't quite get the hang of it.
I wanted for my code to get the arguments and check if they are either even or prime numbers, and if they are, to print them. Additionally make the sum of each one of these kind of numbers.
This is the code:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define something 10
pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
int snrp=0;
int sprim=0;
void * verif(void* argv){
pthread_mutex_lock(&lock);
int x=*(int*)argv;
if (x%2==0){
printf("%d is even\n",x);
snrp+=x;
}
else{
int ok=1;
int d;
if(x<1)
ok=0;
for(d=3;d*d<x;d+=2)
if(x%d==0)
ok=0;
if(ok==0)
return NULL;
printf("%d is prime\n",x);
sprim+=x;
}
pthread_mutex_unlock(&lock);
sleep(1);
return NULL;
}
int main(int argc,char* argv[]){
pthread_t threads[something];
int i,n;
for(i=1;i<argc;i+=1){
n=atoi(argv[i]);
if(pthread_create(&threads[i],NULL,verif,(void*) &n))
printf("Error");
}
for(i=1;i<argc;i+=1)
pthread_join(threads[i],NULL);
printf("Even numbers sum is %d \n",snrp);
printf("Prime numbers sum is %d \n",sprim);
pthread_mutex_destroy(&lock);
return 0;
}
If I use for example the arguments 2,3,5 I get the output:
5 is prime
5 is prime
5 is prime
Even numbers sum is 0
Prime numbers sum is 15
Can someone please explain why?
#Darkmer
void * verif(void* argv){
pthread_mutex_lock(&lock);
int x=*(int*)argv;
printf("%p stores %d",argv,n); // Add this line. in your code.
You will understand, every time you are sending same address, thus same n ( which is 5 in your sample). Why this happened? that happened because before the thread used n, you parallely changed it in main function with next command line argument.
This happened, because in main program, you used same 'n' for all three parameters. Instead, postpone the atoi function and use it inside verif(). pass argv directly from command line arguments. I can do that pthread_create(..) function change for you, but that is your home work.
good luck.
Your verif function can return without releasing the lock here:
if(ok==0)
return NULL;
That will leave the lock held forever and any other thread that tries to acquire it will wait forever.
Also, this is wrong:
for(i=1;i<argc;i+=1){
n=atoi(argv[i]);
if(pthread_create(&threads[i],NULL,verif,(void*) &n))
printf("Error");
}
You pass the thread the address of n, but what is it supposed to do with that address? The value of n is modified in this code with no synchronization, so the new thread cannot legally access it. Instead of passing the thread the address of n, pass it the value of n.
You send the same parameter for your thread.
int main(int argc,char* argv[]){
pthread_t threads[something];
int i;
int n[3] = {2, 3, 5};
for(i=0;i<3;i+=1)
{
if(pthread_create(&threads[i],NULL,verif,(void*) &n[i]))
printf("Error");
}
for(i=0;i<3;i+=1)
pthread_join(threads[i],NULL);
printf("Even numbers sum is %d \n",snrp);
printf("Prime numbers sum is %d \n",sprim);
pthread_mutex_destroy(&lock);
return 0;
}
Notice: pthread_create(&threads[i],NULL,verif,(void*) &n[i])
Here is the link:
http://linux.die.net/man/3/pthread_create
So i have the following problem: Implement a program that gets as arguments a file name followed by words. For each word, create a separate thread that counts its appearances in the given file.Print out the sum of the appearances of all words.
I'm also not sure if my code is really formatted correctly. I'm trying to figure out how to get each word to be counted in the given text file. I am trying to test out this code but I am getting a couple errors from it, the biggest being a segmentation error. If you have any pointers or advice or help, please let me know.
my code is:
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include <pthread.h>
pthread_mutex_t mtx; // used by each of the three threads to prevent other threads from accessing global_sum during their additions
int global_sum = 0;
typedef struct{
char* word;
char* filename;
}MyStruct;
void *count(void*str)
{
MyStruct *struc;
struc = (MyStruct*)str;
const char *myfile = struc->filename;
FILE *f;
int count=0, j;
char buf[50], read[100];
// myfile[strlen(myfile)-1]='\0';
if(!(f=fopen(myfile,"rt"))){
printf("Wrong file name");
}
else
printf("File opened successfully\n");
for(j=0; fgets(read, 10, f)!=NULL; j++){
if (strcmp(read[j],struc->word)==0)
count++;
}
printf("the no of words is: %d \n",count);
pthread_mutex_lock(&mtx); // lock the mutex, to prevent other threads from accessing global_sum
global_sum += count; // add thread's count result to global_sum
pthread_mutex_unlock(&mtx); // unlock the mutex, to allow other threads to access the variable
}
int main(int argc, char* argv[]) {
int i;
MyStruct str;
pthread_mutex_init(&mtx, NULL); // initialize mutex
pthread_t threads[argc-1]; // declare threads array
for (i=0;i<argc-2;i++){
str.filename = argv[1];
str.word = argv[i+2];
pthread_create(&threads[i], NULL, count, &str);
}
for (i = 0; i < argc-1; ++i)
pthread_join(threads[i], NULL);
printf("The global sum is %d.\n", global_sum); // print global sum
pthread_mutex_destroy(&mtx); // destroy the mutex
return 0;
}
The second good bit of advice for today is to look carefully at the warnings that your compiler gives you and take heed of them. strcmp(read[j],struc->word) Your compiler must have warned you that that is wrong. You are passing a single char as the first parameter instead of const char *. That'll almost certainly result in a seg fault. – kaylum
i am trying to implement Dining Philosophers in C using Resource hierarchy solution. when i am using valgrind everything goes fine. Unfortunately when i done this using console im getting random seqfaults. One time my program will be succesful,one time it will broke on the beginning. I would be grateful if anybody could point where i did mistake and why it's 100% succesfull.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define NUM_PHILOSPHERS 5
sem_t forks[NUM_PHILOSPHERS];
void *philosopher(void *param){
printf("Thread created!");
int *id = (int *)param;
int L = 0;
sem_t* Myforks[2];
int par = *id;
if(par == 4){
Myforks[0] = &forks[4];
Myforks[1] = &forks[0];
}else{
Myforks[0] = &forks[par];
Myforks[1] = &forks[par+1];
}
while(L!=5){
printf("Eat spaghetti!",*id);
sem_wait(Myforks[0]);
sem_wait(Myforks[1]);
//.....
printf("EAT spaghetti!",*id);
sem_post(Myforks[1]);
sem_post(Myforks[0]);
L=L+1;
}
pthread_exit(NULL);
}
int main(){
int i;
pthread_t threads[NUM_PHILOSPHERS];
for(i = 0; i < NUM_PHILOSPHERS; i++)
sem_init(&forks[i], 0, 1);
for(i = 0; i < NUM_PHILOSPHERS; i++)
pthread_create(&threads[i], NULL, philosopher, (void *)&i);
return 0;
}
int i;
...
for(i = 0; i < NUM_PHILOSPHERS; i++)
pthread_create(&threads[i], NULL, philosopher, (void *)&i);
^^
Passing a pointer to a local variable isn't going to work. You're passing the same address to all of the threads, so there's an inherent race condition. You point them a pointer to i and them almost immediately you increment i. What value will they read when they access *param? Who knows!
You'll want to create an array with NUM_PHILOSPHERS (sic) slots in it and pass a different address to each thread. You'll also want to make sure that array isn't destroyed when main() exits—i.e., make the array global or static, not local.
This is my code. It's very simple.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *func(void *arg)
{
printf("ID=%d\n", *(int*)arg);
pthread_exit(NULL);
}
int main()
{
pthread_t pt[4];
int i;
for (i = 0; i < 4; i++)
{
int temp = i;
pthread_create(&pt[i], NULL, func, (void*)&temp);
}
sleep(1);
return 0;
}
I compiled it:
gcc p_test.c -lpthread
I ran it. It printed 2 2 3 3. I ran it again. It printed 2 3 3 2.
My problem is:
Why was 2 or 3 printed twice?
Why didn't it print 1 3 2 0 or any other results?
The major problem here is that you're taking the address of the local variable temp, and then using that pointer outside the scope of the variable - as soon as you exit one iteration of the loop, your pointer to temp becomes invalid and you must not dereference it.
You're passing a pointer to a temporary variable into the thread creation function and this temporary goes out of scope at the end of the loop block. It would seem to me that the temporary address is being reused by the compiler and so that when the threads are executing, they see the same address location.
If you do:
int *temp = malloc(sizeof(int));
*temp = i;
pthread_create(&pt[i], NULL, func, (void*)temp);
instead, you should see the results you expect.
In this case, the thread function needs to free the int after it is printed it to avoid a memory leak.
Also, it's better practice to pthread_join() the threads that you're waiting for rather than just sleep()ing.
because it prints temp, all threads shares the memory(why temp is "shared" is explained by TheJuice), so all threads "share" temp . Use a mutex or make temp a private variable.
Private Variables in Threads
Or you can use phtread_join like this:
int main()
{
pthread_t pt[4];
int i;
for (i =0 ; i < 4; i++)
{
pthread_create(&pt[i], NULL, func, (void*)&i);
pthread_join(pt[i],NULL);
}
//sleep(1);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *func(void* arg)
{
printf("ID=%d\n", (int)arg);
pthread_exit(NULL);
return 0;
}
int main()
{
pthread_t pt[4];
int i;
for (i =0 ; i < 4; i++)
{
pthread_create(&pt[i], NULL, func, (void*)i);
pthread_join(pt[i],NULL);
}
return 0;
}