In this code, I'm trying to create an array of threads. I've set the pthreads value to 1. In the for loop, the address, ID, and "created" gets printed, but the function never seems to execute as I don't get a print.
The seg fault actually happens at pthread_join at the bottom, but it certainly has to be caused by the creation since the function never runs, right? producers[0] is the only thread since I'm just testing 1. The create function passes an (ID address, NULL, the void * function(), and void* arguments) like it's supposed to. It has to be something obvious but I've tried to figure it out for so long I'm empty.
typedef struct ThreadStruct {
int threadIndex;
} ThreadStruct;
void *producer(void* ts){
printf("in producer\n");
FILE* inputfp = threadstruct->inputFiles[0];
hostname = (char*)malloc((MAXNAME+1)*sizeof(char));
while(fscanf(inputfp, hostname) > 0){
printf("%s",hostname);
}
return 0;
}
int main(int argc, char *argv[]){
int pthreads = atoi(argv[1]); //always 1
ThreadStruct threadstruct;
pthread_t producers[pthreads];
for(int i=0;i<pthreads;i++){
printf("in pthread loop\n");
printf("%p \n",&producers[i]);
printf("%ld \n",producers[i]);
pthread_create(&producers[i], NULL, producer, (void *) &threadstruct);
}
pthread_join(producers[0], NULL);
}
Your code works in my side and would not produce the seg fault.
Here is the print out info:
$ ./pthread
in pthread loop
0xffffcb70
6444554784
in pthread loop
in producer
0xffffcb78
64
in pthread loop
in producer
0xffffcb80
1
in pthread loop
in producer
0xffffcb88
4299166064
in pthread loop
in producer
0xffffcb90
6443761969
in pthread loop
in producer
0xffffcb98
6445451520
in pthread loop
in producer
0xffffcba0
314761761601
in producer
exit main thread
Your code here:
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
typedef struct ThreadStruct {
int threadIndex;
} ThreadStruct;
void *producer(void* ts){
printf("in producer\n");
return 0;
}
int main(int argc, char *argv[]){
int pthreads = 7;
ThreadStruct threadstruct;
pthread_t producers[pthreads];
for(int i=0;i<pthreads;i++){
printf("in pthread loop\n");
printf("%p \n",&producers[i]);
printf("%ld \n",producers[i]);
pthread_create(&producers[i], NULL, producer, (void *) &threadstruct);
}
pthread_join(producers[0], NULL);
printf("exit main thread\n");
}
you don't seem to check if the thread is actually created or not, in other words you don't seem to validate the return type of pthread_create and straight calling pthread_join probably leading to Undefined behavior, in case pthread_create fails.
pthread_create(&producers[i], NULL, producer, (void *) &threadstruct);
from pthread_join
The pthread_join() function shall fail if:
EINVAL The implementation has detected that the value specified by thread does not refer to a joinable thread.
ESRCH No thread could be found corresponding to that specified by the given thread ID.
however there are cases where pthread_join with invalid thread handle seg faults.
a piece of extract from the link above
"*Passing invalid handle to pthread_join is like passing invalid pointer to a system call.
The implementation may detect it and signal it in errno, but it may crash as
well.
There are 2 different POSIX threads implementations on Red Hat Linux
linuxthreads, where pthread_t handle is a small integer (and the number of
threads is substantially limited)
NPTL (the default, pthread_t is internally a pointer so that there are no
arbitrary thread limits)
You can request the old-fashioned threading library with LD_ASSUME_KERNEL=2.4.19
in the environment.
For NPTL where pthread_t is a pointer, pthread_join detects some invalid
handles where it can be done cheaply. But detecting all possible invalid
handles would be very costly (the implementation would basically have to take
a global lock and iterate over all currently running threads, comparing the
handle with each of them. With say 100000 running threads you can see how
costly it is).
This testcase works on SuSE since SuSE only ships the old-fashioned non-scalable
linuxthreads implementation.*"
from pthead_create
RETURN VALUE
On success, pthread_create() returns 0; on error, it returns an error number, and the contents of *thread are undefined.
perhaps something like this
if( pthread_create(&producers[i], NULL, producer, (void *) &threadstruct) ) {
perror("something wrong .. ");
exit(1);
}
Firstly check the return value of pthread_create() to check whether it was successful or not. For e.g
int ret = pthread_create(&producers[i], NULL, producer, (void *) &threadstruct);
if(ret) {
fprintf(stderr, "failed to create thread %s\n",strerror(ret));
exit(EXIT_FAILURE);
}
And Also it's advised to use pthread_join() for all the threads not only first thread, as if you want to wait for thread/s to terminate before further processing in main thread as mentioned here. Also check the return value of pthread_join().
Sample Code
#include<stdio.h>
#include<string.h>
#include<stdint.h>
#include<stdlib.h>
#include<pthread.h>
typedef struct ThreadStruct {
int threadIndex;
} ThreadStruct;
void *producer(void* ts){
printf("in producer\n");
return 0;
}
int main(int argc, char *argv[]){
int pthreads = 5;
int ret;
ThreadStruct threadstruct;
pthread_t producers[pthreads];
/* create threads */
for(intptr_t itr = 0;itr < pthreads; itr++){
printf("in pthread loop\n");
//printf("%p \n",&producers[itr]);
//printf("%ld \n",producers[itr]);
ret = pthread_create(&producers[itr], NULL, producer, (void *) &threadstruct);
if (ret) {
fprintf(stderr, "failed to create thread #%ld - %s\n",(long)itr, strerror(ret));
exit(EXIT_FAILURE);
}
}
/* join all threads */
for(intptr_t itr = 0; itr < pthreads; itr++){
printf("In main: joining thread #%ld\n", (long)itr);
ret = pthread_join(producers[itr], NULL);
if (ret) {
fprintf(stderr, "failed to join thread #%ld - %s\n",(long)itr, strerror(ret));
exit(EXIT_FAILURE);
}
}
//pthread_exit();
return 0;
}
it works in my system, hope it works for you also.
Related
I am learning threads using C and found the following 'Hello World' program. When I am printing the vale of pthread_value() within the thread and outside the thread using pthread_join() the values returned by the two threads are completely different.
/******************************************************************************
* FILE: hello.c
* DESCRIPTION:
* A "hello world" Pthreads program. Demonstrates thread creation and
* termination.
* AUTHOR: Blaise Barney
* LAST REVISED: 08/09/11
******************************************************************************/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 5
void *PrintHello(void *threadid)
{
long tid;
tid = (long)threadid;
printf("Hello World! It's me, thread #%ld!, %ld\n", tid, pthread_self());
long a= pthread_self();
//pthread_exit(NULL);
long *p = &a;
return p;
}
int main(int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
void *status;
long t;
FILE* file = fopen("test.txt", "r");
for(t=0;t<NUM_THREADS;t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
for(t=0; t<NUM_THREADS;t++){
pthread_join(threads[t], &status);
printf("%ld\n",(long)status);
}
/* Last thing that main() should do */
pthread_exit(NULL);
}
Your PrintHello() function returns the address of a local variable. Trying to use that address after the function exits is undefined and anything can happen, from getting a garbage value to your program crashing. Plus instead of dereferencing that address to get at the value it points to (Assuming it was still valid, which, again, it's not), you cast the address to a long and print out the address itself. I doubt that's what you intended to do. The general approach should be to malloc enough memory in the thread to hold its return value, and returning that address. Then in the joining thread, dereference that returned address to get at the actual returned value, and free that memory when done.
I want to create a program that creates a new thread each time a specific method is called. Here is my working code so far:
#define NUMBER_OF_THREADS 3
pthread_t threads[NUMBER_OF_THREADS];
pthread_attr_t attr;
void *BusyWork(void *t)
{
int i;
long tid;
tid = (long)t;
printf("Thread %ld running...\n",tid);
// ...
printf("Thread %ld completed...\n",tid);
pthread_exit((void*) t);
}
void createNewThread(int number){
printf("running createNewThread(%d)\n", number);
pthread_t tid;
int rc = pthread_create( &tid, &attr, BusyWork, (void *) (long)number);
if (rc) {
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
int main(int argc, char *argv[]) {
int i, rc;
//Set up thread attributes
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
//Arbitary amount of calls (My real program will call the createNewThread() funcion multiple unkown amount of times)
createNewThread(15);
createNewThread(27);
createNewThread(62);
createNewThread(500);
createNewThread(8864);
createNewThread(99999);
//Free attributes
pthread_attr_destroy(&attr);
//Wait for other threads still running
// HOW CAN I DO THIS????
/*for (i=0; i< NUMBER_OF_THREADS; i++){
rc = pthread_join( ??? , NULL); //TODO
if (rc){
printf("ERROR: return code from pthread_join() %d\n", rc);
exit(-1);
}
printf("Main: completed join with thread %d\n", i);
}*/
printf("Main: program completed. Exiting.\n");
pthread_exit(NULL); // (?) Is this part nessassary as we are on the main thread and soon to exit the program
return 0;
}
However as you can see in my code there is a few issues! For example, how can I wait for all processes to complete for the code I am using, as I am not keeping track of the thread number. Also when a thread "BusyWork" is done it does not clean up after it self and left as an orphan process.
One idea I had was to use a vector to keep track of each thread number and then use that for the final join at the end of main. However the problem with that is the array list can easily get very large and will never shrink even though a thread is complete.
Detach the threads, don't join them. Before you create a thread, increment a counter protected by a mutex. Right before a thread terminates, acquire the mutex and decrement the counter. Now you know all threads are done when the counter reads zero. You can use a condition variable to make the counter waitable if you like.
I'm trying to implement merge sort with semaphores and I have some troubles making my code running:
sem_t *sem;
pthread_t *t;
void *parallel_merge_sort(void *thread_id)
{
int a = *((int *) thread_id);
printf("%d. in sort\n",a);
fflush(stdout);
sem_post(&(sem[a]));
if(a % 2)
sem_wait(&(sem[a-1]));
else
sem_wait(&(sem[a+1]));
printf("%d. out sort\n",a);
fflush(stdout);
}
void main()
{
int P = 2,i;
t = calloc(P,sizeof(pthread_t));
sem = calloc(P,sizeof(sem_t));
printf("threads created\n");
fflush(stdout);
for(i=0;i<P;i++)
pthread_create(&(t[i]),NULL,(void*) ¶llel_merge_sort,(void *) &i);
for(i=0;i<P;i++)
pthread_join(t[i], NULL);
printf("threads end\n");
fflush(stdout);
}
This code produces output like the following one:
threads created
0. in sort
0. in sort
After this, it doesn't continue to run and wait.
What can the problem be and how can I fix it?
There's no guarantee that a new thread starts immediately. This means that you can't use a pointer to the index as the variable may change before the thread starts.
In this case it seems that the threads doesn't start until the main thread have entered the second loop, in which the variable i is reset to zero, so both threads will have the same index, making both threads to try to wait on the same semaphore.
You can bypass this by using a "hack" and pass i directly as the pointer:
pthread_create(&(t[i]),NULL,(void*) ¶llel_merge_sort,(void *) i);
And in the thread function do:
int a = (int) thread_id;
i have this piece of code:
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <time.h>
int number;
pthread_mutex_t *mutex;
pthread_t *threads;
void *PrintHello(void *threadid)
{
long tid;
tid = (long)threadid;
printf("Hello World! It's me, thread #%ld!\n", tid);
time_t rawtime;
struct tm * time_start;
time ( &rawtime );
time_start = localtime ( &rawtime );
printf ( "The number %ld thread is created at time %s \n",tid, asctime (time_start));
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
int i,rc;
printf("give threads");
scanf("%d",&number);
mutex = calloc( number, sizeof(*mutex));
threads = calloc(number, sizeof(*threads));
for (i = 0; i < number;i++) {
pthread_mutex_init( &mutex[i],NULL);
}
for(i=0; i<number; i++){
printf("In main: creating thread %d\n", i);
rc = pthread_create(&threads[i], NULL, PrintHello, (void *)i);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
return 0;
}
The purpose of this code is to ask the user to give the number of the threads that it is going to create and after the creation of the threads,the thread itself will print 2 messages saying the number of the thread and the time that it was created.
The problem is that inside the main the message "In main: creating thread" is showing up but the message inside the threads sometimes does not.
For example, it would create 3 threads and only 1 thread will show up its message and that thread also will not show up the time that was created. I dont know if there is something wrong with the code.
Root Cause:
Your main() exits before the child threads get an opportunity to complete their task.
Solution:
You need to make sure that the main() waits until all the threads have completed their work.
You need to use:
pthread_join()
to achieve this functionality. Add the following before returning from main():
for(i=0; i<number; i++)
{
pthread_join(threads[i], NULL);
}
Other problems:
You allocate memory dynamically but never deallocate it. Eventhough, the OS reclaims the memory once your program returns. It is a good practice to do so explicitly.
You created a mutex but you neither use it, nor deallocate it. But that seems to be code in progress.
Return from main() is equivalent to calling exit(...), which terminates the whole process. You may use pthread_join() to wait for each non-main thread, like another answer advises, or you may call pthread_exit(NULL) in the end of your main(): it would exit the initial thread, but other threads will continue to run.
I'm writing a Unix application in C which uses multiple threads of control. I'm having a problem with the main function terminating before the thread it has spawned have a change to finish their work. How do I prevent this from happening. I suspect I need to use the pthread_join primitive, but I'm not sure how. Thanks!
Yes, you could use pthread_join() (see other anwers for how to do that). But let me explain the pthread model and show you another option.
In Unix, a process exits when the primary thread returns from main, when any thread calls exit() or when the last thread calls pthread_exit(). Based on the last option, you can simply have your main thread call pthread_exit() and the process will stay alive as long as at least one more thread is running.
Yes one of doing this is to use pthread_join function: that's assuming your thread is in "joinable" state.
pthread_create: after this function returns control, your thread will be executing your thread function.
after pthread_create, use the tid from pthread_create to pthread__join.
If your thread is detached, you must use some other technique e.g. shared variable, waiting on signal(s), shared queue etc.
Great reference material available here.
There are a number of different ways you can do this, but the simplest is to call pthread_exit() before returning from main().
Note that this technique works even if the thread you want to wait for is not joinable.
You may want to look at this page:
http://publib.boulder.ibm.com/iseries/v5r2/ic2924/index.htm?info/apis/users_25.htm
rc = pthread_create(&thread, NULL, threadfunc, NULL);
checkResults("pthread_create()\n", rc);
printf("Wait for the thread to exit\n");
rc = pthread_join(thread, &status);
Check this simple C code I wrote for one of my libraries
/*
* Copyright (c) 2011 Dino Ciuffetti <dino#tuxweb.it>, TuxWeb S.r.l., NuvolaBase Ltd
*
* This file is part of liborient.
*
* Liborient is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Liborient is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Liborient. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
//pthread_rwlock_t ptr_thr_lock = PTHREAD_RWLOCK_INITIALIZER;
typedef struct {
int t;
} thread_arguments;
void *thread_stuff(void *args) {
thread_arguments *t_args;
int tid;
t_args = (thread_arguments *)args;
//pthread_rwlock_rdlock(&ptr_thr_lock);
tid = t_args->t;
//pthread_rwlock_unlock(&ptr_thr_lock);
/*while (1) {
sleep (1);*/
printf("Thread #%i!\n", tid);
/*}*/
t_args = NULL;
pthread_exit(NULL);
return NULL;
}
int wait_threads(pthread_t threads[], thread_arguments *t_args[], int nthreads) {
int t;
int rc;
// Waiting for threads termination
for(t=0; t<nthreads; t++) {
rc = pthread_join(threads[t], NULL);
free(t_args[t]);
if (rc != 0) {
printf("Error waiting for termination of thread %i: %i\n", t, rc);
return 1;
break;
}
}
return 0;
}
int spawn_threads(pthread_t threads[], thread_arguments *t_args[], int nthreads) {
int t;
int rc;
// Spawning threads
for(t=0; t<nthreads; t++) {
t_args[t] = (thread_arguments *) malloc(sizeof(thread_arguments));
//pthread_rwlock_wrlock(&ptr_thr_lock);
t_args[t]->t = t;
//pthread_rwlock_unlock(&ptr_thr_lock);
printf("Spawning thread: %i\n", t);
rc = pthread_create(&threads[t], NULL, (void *)thread_stuff, (void *)t_args[t]);
if (rc != 0) {
printf("Error spawning thread %i: %i\n", t, rc);
wait_threads(threads, t_args, rc+1);
return t+1;
break;
}
}
return 0;
}
int main() {
pthread_t threads[20];
thread_arguments *t_args[20];
int rc;
rc = spawn_threads(threads, t_args, 20);
if (rc > 0) {
printf("Failed spawning thread number %i\n", rc-1);
return 1;
}
rc = wait_threads(threads, t_args, 20);
return 0;
}