This question already has answers here:
Undefined reference to pthread_create in Linux
(16 answers)
Closed 1 year ago.
So I am writing a program in C that creates 4 threads that produce/consume from buffers. I initialized all the threads in my main function but I am getting the following error. Does anyone know why? I ran it on my local zsh shell on macOS and it works fine. But when I try running it on my school's server, I think it's linux with bash, it gives me the errors.
flip1 ~/CS344/assignment4 1022$ gcc -std=gnu99 -o line-processor line_processor2.c
/tmp/ccYF7Kqe.o: In function `main':
line_processor2.c:(.text+0x7b5): undefined reference to `pthread_create'
line_processor2.c:(.text+0x7d9): undefined reference to `pthread_create'
line_processor2.c:(.text+0x7fd): undefined reference to `pthread_create'
line_processor2.c:(.text+0x821): undefined reference to `pthread_create'
line_processor2.c:(.text+0x832): undefined reference to `pthread_join'
line_processor2.c:(.text+0x843): undefined reference to `pthread_join'
line_processor2.c:(.text+0x854): undefined reference to `pthread_join'
line_processor2.c:(.text+0x865): undefined reference to `pthread_join'
collect2: error: ld returned 1 exit status
Below is my main function
int main()
{
pthread_t inputThread, lineSeparatorThread, plusSignThread, outputThread;
pthread_attr_t attr;
// Set up Sentinal Values at the begining of each buffer to indicate whether or not
// the buffer line has been read or not
for (int i = 0; i < BUFSIZE; i++)
{
buffer1[i][0] = -1;
buffer2[i][0] = -1;
buffer3[i][0] = -1;
}
// Initialize a pthread attribute structure to set up joinable threads
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
// Initialize mutex and condition variables
pthread_mutex_init(&mutex1, NULL);
pthread_mutex_init(&mutex2, NULL);
pthread_mutex_init(&mutex3, NULL);
pthread_cond_init(&readyBuffer1, NULL);
pthread_cond_init(&readyBuffer2, NULL);
pthread_cond_init(&readyBuffer3, NULL);
// Set up the thread in reverse order so that the readers/consumers will pend
// waiting for the writers/consumers to start up
pthread_create(&outputThread, &attr, output_thread, NULL);
usleep(100); // Force the program to allow output thread to actually come up and pend on readyBuffer 3 first
pthread_create(&plusSignThread, &attr, plus_sign_thread, NULL);
usleep(100); // Force the program to allow plus_sign_thread thread to actually come up first
pthread_create(&lineSeparatorThread, &attr, line_separator_thread, NULL);
usleep(100); // Force the program to allow line_separator_thread thread to actually come up first
pthread_create(&inputThread, &attr, input_thread, NULL);
pthread_join(inputThread, NULL);
pthread_join(lineSeparatorThread, NULL);
pthread_join(plusSignThread, NULL);
pthread_join(outputThread, NULL);
// Freeing up memory.
pthread_attr_destroy(&attr);
pthread_mutex_destroy(&mutex1);
pthread_mutex_destroy(&mutex2);
pthread_mutex_destroy(&mutex3);
pthread_cond_destroy(&readyBuffer1);
pthread_cond_destroy(&readyBuffer2);
pthread_cond_destroy(&readyBuffer3);
return 0;
}
And lastly, my #include statements and buffer variables.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <ctype.h>
#define BUFSIZE 50
// Buffers can hold up to 50 lines that can be 1000 characters.
char buffer1[BUFSIZE][1000]; //inputThread + lineSeparatorThread
char buffer2[BUFSIZE][1000]; //lineSeparatorThread + plus_sign_thread
char buffer3[BUFSIZE][1000]; //plus_sign_thread + output_thread
Its look like your'e missing compilation flag -pthread.
try to put the flag as last.
gcc test.c -o test -std .... -pthread
From man7:
int pthread_create(pthread_t *restrict thread,
const pthread_attr_t *restrict attr,
void *(*start_routine)(void *),
void *restrict arg);
Compile and link with -pthread.`
https://man7.org/linux/man-pages/man3/pthread_create.3.html
Related
I'm having trouble compiling my code, which uses a mutex (so uses pthread locks and conditions). I've tried including the header file, compiling with -pthread or -lpthread, but I'm still getting an error. Help would be much appreciated.
This is the error output:
implicit declaration of function ‘Pthread_mutex_lock’ [-Wimplicit-function-declaration]
Pthread_mutex_lock(&lock); //locked
^
/tmp/cchVS47i.o: In function getMessage1':
hw3.c:(.text+0x22): undefined reference toPthread_mutex_lock'
hw3.c:(.text+0x50): undefined reference to Pthread_mutex_lock'
/tmp/cchVS47i.o: In functiongetMessage2':
hw3.c:(.text+0x13e): undefined reference to `Pthread_mutex_lock'
collect2: error: ld returned 1 exit status
And here's relevant sections of my code (edited for clarity):
#define _GNU_SOURCE
#include<stdio.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#include<stdlib.h>
char message[1001];
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t condition = PTHREAD_COND_INITIALIZER;
void *getMessage1()
{
Pthread_mutex_lock(&lock); //locked
....
}
int main(void)
{
pthread_t id1;
pthread_t id2;
pthread_create((&id1), NULL, getMessage1, NULL);
pthread_create((&id2), NULL, getMessage2, NULL);
...
return 0;
}
It's the capital P you have in
Pthread_mutex_lock(&lock); //locked
in the beginning of the function getmessage1().
Your compiler is complaining that it has not seen a declaration for that function in the compiling phase. Also it is complaining about that in the linking phase. You are including all the right libraries because it is not complaining about any of the other functions that are correctly typed.
The correct name of the function is pthread_mutex_lock().
In original k&r C it is possible to use functions without declarations, although compilers warn about them. In more modern versions of C (99) this has been deprecated.
I am trying to make sense of a program:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
int main(int argc, char** argv) {
volatile double fShared = 0.0;
// create pthread structures - one for each thread
pthread_t t0;
pthread_t t1;
//Arbitrary pointer variables - void* is a pointer to anything
void *thread_res0;
void *thread_res1;
int res0,res1;
//create a new thread AND run each function
// we pass the ADDRESS of the thread structure as the first argument
// we pass a function name as the third argument - this is known as a FUNCTION pointer
// you might want to look at the man pages for pthread_create
res0 = pthread_create(&t0, NULL, do_this, (void*)"");
res1 = pthread_create(&t1, NULL, do_that, (void*)"");
// Two threads are now running independently of each other and this main function
// the function main is said to run in the main thread, so we are actually running
// The main code can now continue while the threads run - so we can simply block
res0 = pthread_join(t0, &thread_res0);
res1 = pthread_join(t1, &thread_res1);
printf ("\n\nFinal result is fShared = %f\n",fShared);
return (EXIT_SUCCESS);
}
It should be noted that do_this and do_that are functions created earlier in the program. I am getting the following errors:
seed#ubuntu:~/Programs$ Homework2OS.c
/tmp/cceiRtg8.O: in function 'main'
Undefined reference to 'pthread_create'
Undefined reference to 'pthread_create'
Undefined reference to 'pthread_join'
Undefined reference to 'pthread_join'
We were given this bit of code to fix. I have found elsewhere the format for the pthread_create constructor. Do I need to actually define it above the main? I was under the impression it was imported with the library.
I would also venture to guess that it has something to do with the fourth parameter? I understand that the first parameter is the location of the thread (defined above), the second is NULLed, the third is the function call but I do not quite understand what the fourth parameter is supposed to be.
What's wrong?
all the code imports is the header for the pthread library. (pthread.h)
What is missing is the linker needs to actually include the library for gcc the parameter -pthread is needed (AT THE END of the list of parameters to gcc.)
It needs to be at the end because the linker processes parameters in the order given on the command line and if the object files are not already processed, then there will not be any unresolved references for the linker to try to resolve via browsing the pthread library.
I.E. this is wrong:
gcc -g -o myprogram -lpthread myprogram.o
This is correct:
gcc -g -o myprogram myprogram.o -lpthread
I asked a question Using sockets in multithread server yesterday. In this question I described segmentation fault under Solaris in multithreaded server. Now I have found the core of error and written code, that shortly demonstrates it:
#include <stdlib.h>
#include <pthread.h>
int main(int argc, char *argv[])
{
pthread_attr_t *attr;
attr = (pthread_attr_t *)malloc(sizeof(pthread_attr_t));
pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED);
malloc(0);
malloc(0); //Segmentation fault there
return 0;
}
Second malloc crashes with Segmentation fault.
While this code executes normally:
#include <stdlib.h>
#include <pthread.h>
int main(int argc, char *argv[])
{
pthread_attr_t *attr;
attr = (pthread_attr_t *)malloc(sizeof(pthread_attr_t));
// pthread_attr_setdetachstate(attr, PTHREAD_CREATE_DETACHED);
malloc(0);
malloc(0);
return 0;
}
Could you please explain the reason of the error?
P.S.: I compile with gcc -pthreads -lpthread -D_REENTRANT keys.
From the docs on pthread_attr_setdetachstate():
The behavior is undefined if the value specified by the attr argument to pthread_attr_getdetachstate() or pthread_attr_setdetachstate() does not refer to an initialized thread attributes object.
It's possible that the pthread_attr_t object the attr argument points to contains a pointer to some state maintained by the pthreads library. If it hasn't been initialized, that pointer would be garbage so the pthread_attr_setdetachstate() call might corrupt the heap.
See the pthread_attr_init() function to see how to properly initialize the attributes object.
I'm trying the code from Tanenbaum's 3e "Modern Operating Systems" and I get compiler errors and warnings:
$ LANG=en_US.UTF-8 cc thread.c
thread.c: In function ‘main’:
thread.c:19:63: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
thread.c:25:1: warning: passing argument 1 of ‘exit’ makes integer from pointer without a cast [enabled by default]
/usr/include/stdlib.h:544:13: note: expected ‘int’ but argument is of type ‘void *’
/tmp/ccqxmMgE.o: In function `main':
thread.c:(.text+0x57): undefined reference to `pthread_create'
collect2: ld returned 1 exit status
This is the code I'm trying
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUMBER_OF_THREADS 10
void *print_hello_world(void *tid)
{
//printf("Hello World. Greetings from thread %d0", tid);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_t threads[NUMBER_OF_THREADS];
int status, i;
for(i=0; i<NUMBER_OF_THREADS; i++) {
//printf("Main here creating thread %d0", i);
status = pthread_create(&threads[i], NULL, print_hello_world, (void *)i);
if (status != 0) {
//printf("Oops. pthread_create returned error code %d0", status);
exit(-1);
}
}
exit(NULL);
}
Can you help me improve the state of the code so that it will run? There appears to be some errata since the exact code from the book doesn't compile. Thanks
Please link to pthread library, by specifying -lpthread option to your linker.
Also, you should be using pthread_join to wait for all the created threads to complete.
$gcc thread.c -lpthread
This is to link the pthread shared library.
1) You have to link to libpthread to get rid of the linker error:
gcc ..... -lpthread
(note that the -lpthread option must be the last one)!
2) exit(NULL); is wrong; NULL is for pointer types whereas exit wants an int to be supplied; use simply
exit(0);
instead.
The other warnings are just system-dependent pointer and integer size warnings; they can safely be ignored in most cases.
Pl. do not use the exit statement in your main function in this case, since the main may get exited and your threads also will terminate and you may not get the outputs of the print statement in the thread function.
Pl. use pthread_exit instead of exit in main so that even your main thread terminates the other threads can continue.
I have used the following code to create two threads:
//header files
#include <pthread.h>
struct thread_arg
{
int var1;
int var2;
};
void *serv_com(void *pass_arg)
{
struct thread_arg *con = pass_arg;
//required statements irrelevant to the issue
pthread_exit(NULL);
}
void *cli_com(void *pass_arg)
{
struct thread_arg *con = pass_arg;
//required statements irrelevant to the issue
pthread_exit(NULL);
}
int main()
{
pthread_t inter_com;
//necessary code
while(1)
{
th_err_s = pthread_create(&inter_com, NULL, serv_com, (void *)&pass_arg);
th_err_c = pthread_create(&inter_com, NULL, cli_com, (void *)&pass_arg);
if (th_err_s || th_err_c)
{
printf("Alert! Error creating thread! Exiting Now!");
exit(-1);
}
}
pthread_exit(NULL);
return 1;
}
Then I compiled the above code in linux using the following command:
gcc -o sample sample.c
It returned the following error message:
inter.c:(.text+0x374): undefined reference to `pthread_create'
inter.c:(.text+0x398): undefined reference to `pthread_create'
collect2: ld returned 1 exit status
What should I do to correctly compile this file. I am sure it is no syntax error or anything since when I commented off everything inside the while loop, the program was compiling correctly and I verified that the pthread_create syntax is correct. Do I have to issue some other command to compile the file?
EDIT: Is there any problem with the creating of two threads in the above code? The program is just exiting with the error message once it is running. What can be the possible issue and how can I solve it? Thanks in advance.
Try doing this :
gcc -lpthread sample.c
or
gcc -pthread sample.c
above 2 commands will directly create executable a.out
Answer after edit:
1) Wait for the two threads to join main thread using call
int pthread_join(pthread_t thread, void **value_ptr);
2) Create both threads with different ids
3) Also avoid calling pthread_exit from main() if you can, although there is no harm doing that
4) you are calling pthread_create in while(1) this will create infinite threads .. I do not know what are you trying to achieve .
Link to pthread Library when compiling...
gcc -o sample -lpthread sample.c
I am not too sure myself but I would think you could do something like
pthread_t inter_com, inter_com2;
and
th_err_s = pthread_create(&inter_com, NULL, serv_com, (void *)&pass_arg);
th_err_c = pthread_create(&inter_com2, NULL, cli_com, (void *)&pass_arg);
I think it should give you 2 ids of threads. But careful when sharing variables etc between threads. But am glad you resolved it yourself.