I'm doing a really easy program using pthreads but i keep getting a "Segmentation fault error" and I cannot understand why. The program is to be compiled in C language.
The program should create 3 threads, each of them should print its number and its calling thread number (in this case , i just want 3 threads to say "I'm thread (i) and the calling thread is 0 " since they are all created from the same thread)
The problem, I think, is with the malloc function used to allocate memory to be passed.
In case this is te problem, how can i solve it?
Should I create an array of 3 pointers before the "for" loop, and store in each pointer of this array the two variables i want to pass to the thread? How to actualy do it? I tried but it doesn't seem to work.
#include<stdio.h>
#include<pthread.h>
#include<unistd.h>
#include<stdlib.h>
void *Son (void* arg)
{int *id=(int*)arg; //retrieve array
sleep(id[1]+1);
printf("I'm thread %d , created from %d! \n",id[1],id[0]);
free(arg);
pthread_exit(0);
}
int main()
{pthread_t threads[3];
int i;
for (i=0;i<3;i++)
{int *a= malloc(2*sizeof(int)); // dynamically allocate a variable which will be freed in the thread once executed
a[0]=0; //store i in the content of dynamically allocated a
a[1]=i;
pthread_create(&threads[i],NULL,Son ,(void*)a);
}
int j;
for (j=0;j<3;i++)
{pthread_join(threads[i],NULL);
printf("Joined thread %d",j);
}
printf("THREAD FINISHED\n");
return 0;
}
Here:
for (j=0;j<3;i++)
{
pthread_join(threads[i],NULL);
printf("Joined thread %d",j);
}
you probably wanted to use threads[j] instead of threads[i]. i, at this point is 4 and you are accessing an invalid memory address via the pthread_join. Also, you need to use j++ instead of i++.
Related
I'm new to using pthreads. I want to create a program where six different threads will each output a different number. The threads can run in any order, however, each thread should run only once.
So, a possible output would be:
Thread: 5
Thread: 2
Thread: 3
Thread: 6
Thread: 1
Thread: 4
Or it could be in any other order.
#include<stdio.h>
#include<pthread.h>
void *apples(void *void_apple_num){
int *thread_num = (int *) void_apple_num;
printf("Thread: %d\n", *thread_num);
return NULL;
}
int main(){
pthread_t threads[6];
int apple_num;
for(apple_num=0; apple_num<6; apple_num++){
pthread_create(&threads[apple_num], NULL, apples, &apple_num);
}
for(apple_num=0; apple_num<6; apple_num++){
pthread_join(threads[apple_num], NULL);
}
return 0;
}
When I run the program, I have this problem of the threads interfering with each other. I am not sure if some of the threads are running twice? However, I think the problem is some of the threads are using the apple_num pointer from a different thread.
Here are two sample outputs I got:
Output 1:
Thread: 5
Thread: 0
Thread: 1
Thread: 1
Thread: 2
Thread: 2
Output 2:
Thread: 1
Thread: 4
Thread: 4
Thread: 5
Thread: 1
Thread: 1
I don't fully understand what is causing the problem. I've heard that threads can sometimes share variables? I don't know if I should use a mutex lock to somehow get the threads to run one-at-a-time.
How can I edit my code to solve this?
If somebody else has asked a similar question, please direct me to their question. I couldn't find anything when I researching.
Each of your threads gets a pointer to the very same local variable apple_num which is being changed in the loop by the main thread. Since threads start asynchronously, the value of local variable apple_num in the main thread is indeterminate from the perspective of any other thread.
You need to pass a copy of that variable to each thread.
One fix is to cast int to void* and back:
void *apples(void* apple_num){
int thread_num = (int)void_apple_num;
...
pthread_create(&threads[apple_num], NULL, apples, (void*)apple_num);
As they mention in the comments, intptr_t and uintptr_t (from <stdint.h>) may be more appropriate for round-trip without loss, e.g. uintptr_t -> void* -> uintptr_t. But C standard doesn't require any integers to round-trip to void* and back, it only requires void* -> intptr_t and back.
In a more realistic scenario, you may like to pass more than just one integer to a thread, namely, a struct. And that's the rationale for the thread start function to receive a single void* argument - it can point to an object of any data type (POSIX requires void* to also be able to store function pointers).
An example of passing a structure to a thread (without relying on implementation-defined conversion of integers to void* and back):
struct ThreadArgs {
int thread_num;
// More data members, as needed.
};
void* apples(void* arg){
struct ThreadArgs* a = arg;
printf("Thread: %d\n", a->thread_num);
free(arg);
return NULL;
}
int main() {
pthread_t threads[6];
struct ThreadArgs* a;
int apple_num;
for(apple_num=0; apple_num<6; apple_num++){
a = malloc(sizeof *a);
a->thread_num = apple_num;
pthread_create(&threads[apple_num], NULL, apples, a);
}
for(apple_num=0; apple_num<6; apple_num++)
pthread_join(threads[apple_num], NULL);
return 0;
}
Note, that you don't have to allocate the thread arguments structure on the heap (malloc). If you pass an automatic variable (on the stack) to a thread, you must make sure that the variable is unchanged and still exists when the thread accesses it. Allocating the thread arguments structure from the heap is the safest and solves this problem at the expense of malloc/free calls.
can someone please explain exactly what memory is being shared between threads? I got the code from a website just so I can explain what I don't understand exactly. I want to know, if all the threads after they're created they will execute the function doSomeThing and will they share the same value for MyVariable or every thread will have separate values for it. (ignore the fact that there isn't any value assigned to the variable)
#include<stdio.h>
#include<string.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
pthread_t tid[2];
void* doSomeThing(void *arg)
{
unsigned long i = 0;
int MyVariable;
pthread_t id = pthread_self();
if(pthread_equal(id,tid[0]))
{
printf("\n First thread processing\n");
}
else
{
printf("\n Second thread processing\n");
}
for(i=0; i<(0xFFFFFFFF);i++);
return NULL;
}
int main(void)
{
int i = 0;
int err;
while(i < 2)
{
err = pthread_create(&(tid[i]), NULL, &doSomeThing, NULL);
if (err != 0)
printf("\ncan't create thread :[%s]", strerror(err));
else
printf("\n Thread created successfully\n");
i++;
}
return 0;
}
You've actually asked two separate questions.
what memory is being shared between threads?
Well, all memory (on typical OSes). A main difference between threads and processes is that different processes have different memory spaces, which threads within a process have the same memory space.
See also:
What is the difference between a process and a thread?
will [the two threads] share the same value for MyVariable?
No! and that's because each thread has its own stack (and their own registers state). Now, the stacks are both in the shared memory space, but each thread uses a different one.
So: Sharing memory space is not the same as sharing the value of each variable.
Firstly, I'm Italian and sorry for my bad English.
Anyway, I should do this exercise:
"Write in C a programm which generate a thread. The main shows odd number from 1 to 9, the thread shows even number from 2 to 10. Synchronize the main and the thread with semaphores"
I have written the pseudocode in this way:
//semaphores
semParent = free
semChild = busy
main
generate thread "child"
for i=1 to 9 step 2
P(semParent)
print i
V(semChild)
end for
end main
child
for i=2 to 10 step 2
P(semChild)
print i
V(semParent)
end child
And this is how I have implemented in C:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
pthread_mutex_t semParent;
pthread_mutex_t semChild = PTHREAD_MUTEX_INITIALIZER;
void* functionChild (void* arg) {
for(int i=2; i<=10; i+=2) {
pthread_mutex_lock(&semChild);
printf("CHILD: %d\n",i);
pthread_mutex_unlock(&semParent);
}
return NULL;
}
int main(void) {
pthread_t child;
pthread_create(&child, NULL, &functionChild, NULL);
pthread_mutex_init(&semParent, NULL);
for(int i=1; i<=9; i+=2) {
pthread_mutex_lock(&semParent);
printf("PARENT : %d\n",i);
pthread_mutex_unlock(&semChild);
}
pthread_join(child, NULL);
}
But the output is always different whenever I run the program.
What's wrong?
I use CygWin64 Terminal in Windows 10 64 bit.
Thanks in advance.
A pthread_mutex_t is not a semaphore (though a semaphore can be used as a mutex if you do a "V" to initialize it to "free"). The semaphore API is sem_init, sem_post and sem_wait.
By using pthread_mutex_unlock on a mutex that was locked by another thread, your program is triggering undefined behavior.
This may not be the cause of the problem you are experiencing now, but you should never use printf() in a multithreaded program. printf() writes to a buffer and doesn't always print to the screen right away. Instead you should use sprintf() and write:
char buff[20];
sprintf("PARENT: %d\n", i);
write(1, buff, strlen(buff));
I think that pthread_mutex_init(&semParent, NULL) with NULL attributes and PTHREAD_MUTEX_INITIALIZER have the same effect, which is both locks are initialised to unlocked. Your problem though does not have a critical section with the strict meaning. So a better solution whould be condition variables as #Serhio mentioned. You can also check out semaphores http://www.csc.villanova.edu/~mdamian/threads/posixsem.html which give bigger freedom and can also have the functionality of mutexes.
Below program gives me segmentation fault(core dumped) error on random instances. sometimes it runs without any error. The program is just for understanding deadlocks.
Even though I have run this program for about 15 times, I haven't faced a deadlock so far. Sometimes the program runs smoothly(which can be expected) and sometimes it gives the segmentation fault(which is not expected). Why do I get the segmentation fault?
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
int a=5;
int b=3;
pthread_mutex_t mutex1,mutex2;
void* add_subtract(){
pthread_mutex_lock(&mutex1);
pthread_mutex_lock(&mutex2);
a=a+2;
b=b-2;
printf("%d %d\n",a,b);
pthread_mutex_unlock(&mutex2);
pthread_mutex_unlock(&mutex1);
}
void* subtract_add(){
pthread_mutex_lock(&mutex2);
pthread_mutex_lock(&mutex1);
b=b-2;
a=a+2;
printf("%d %d\n",a,b);
pthread_mutex_unlock(&mutex1);
pthread_mutex_unlock(&mutex2);
}
int main(){
pthread_t thread1,thread2;
pthread_create(&thread1,NULL,add_subtract(),NULL);
pthread_create(&thread2,NULL,subtract_add(),NULL);
pthread_join(thread1,NULL);
pthread_join(thread2,NULL);
return 0;
}
When you pass add_subtract() as an argument, you're calling the function and then passing the return value as the argument. In this case you want to pass the function itself... try it without the parens.
I think you need to initialize the mutex: http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_mutex_init.html
The pthread_mutex_init() function initialises the mutex referenced by
mutex with attributes specified by attr. If attr is NULL, the default
mutex attributes are used; the effect is the same as passing the
address of a default mutex attributes object. Upon successful
initialisation, the state of the mutex becomes initialised and
unlocked.
This question already has answers here:
Wrong thread IDs in a multithreaded C program?
(2 answers)
Closed 8 years ago.
I compiled this code and the 99th threads that it's been created keeps creating more than one thread of number 99. Instead if i insert values from 1-10 or something small then the results are quite normal.
Here is the code.
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
pthread_mutex_t m=PTHREAD_MUTEX_INITIALIZER;
pthread_attr_t attr;
void* test(void *a)
{
int i=*((int *)a);
printf("The thread %d has started.\n",i);
pthread_mutex_lock(&m);
usleep(10000);
printf("The thread %d has finished.\n",i);
pthread_mutex_unlock(&m);
pthread_exit(NULL);
}
int main()
{
int i=0,j=0;
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE);
pthread_t thread[100];
for (i=0;i<100;i++)
{
j=i;
pthread_create(&thread[i],&attr,test,&j);
}
for (i=0;i<100;i++)
pthread_join(thread[i],NULL);
return 0;
}
i get:
..../*Normal Results*/
The thread 99 has finished.
The thread 99 has finished.
The thread 99 has finished.
The thread 99 has finished.
The thread 99 has finished.
The thread 99 has finished.
Why is this happening?
You need to keep all theadIds
int indexes[PTHREAD_COUNT];
for (i=0;i<100;i++) {
indexes[i] = i;
pthread_create(&thread[i], &attr, test, &indexes[i]);
}
Each thread is passed the same pointer to the same stack location (j) in your main thread. Without further synchronisation, its undefined when each thread will be scheduled and will run and access j before printing its value.
There are lots of ways you could print out a unique number from each thread, including
malloc a struct which includes (or is) this number in the main thread. Pass it to the child threads which are then responsible for freeing it
(Suggested by Brian Roche below) Declare an array of 100 ints, with values 0, 1, 2, etc. Pass the address of a different array item to each thread.
have each thread lock a mutex then copy/increment a global counter. The mutex could be passed into the thread or another global
pass a semaphore into each thread, signalling it once the number has been accessed. Wait on this semaphore in the main thread
Note that options 3 & 4 involve serialising startup of the threads. There's little point in running multiple threads if you do much of this!
i is the same address as j in your main code, and you sleep of 30 ms in the threads. So all threads have time to run until the first mutex call, then they all stop for (a little over) 30ms, and then print they have finished. Of course, i in the main loop is now 99, because you are finished with the pthread_join loop.
You need to have an array of "j" values [assuming you want all threads to run independently]. Or do something else. It all depends on what you are actually wanting to do.
you are passing the same memory location (&j) as the pointer to data a.
when threads start, they print out the value just assigned to j, which looks OK
But then only one get the lock and went to sleep, all others thus blocked. when the nightmare is over, memory location "a", of course, has a int value 99.