I am recently learning about threads in C, and I have noticed something I consider weird.
Let's take the next code:
#include <stdio.h>
#include <pthread.h>
void *sub_routine(void *p)
{
p = NULL;
printf("This is a sub_routine\n");
return (NULL);
}
int main(int argc, char **argv)
{
void *p;
pthread_t thread;
if (argc < 1)
return (0);
p = argv[1];
pthread_create(&thread, NULL, sub_routine, NULL);
sub_routine(p);
return (0);
}
I use this command line to compile my program:
gcc -Wall -Wextra -Werror -pthread pthreads.c
The expected result is to print This is a sub_routine two times. Well that happens but not 100% of the times. Is there any particular reason for that?
When main returns, it exits the program even if other threads are running. Therefore, it’s possible for the thread you spawned to not get to the printf before the main thread returns, in which case the program ends before you’ll see both messages.
One way to address this is to add a call to pthread_join at the end of main to tell the program to wait for the thread you created to finish running before main returns. That will ensure you always see two printouts.
Add pthread_join(thread, NULL) at the end (just before return) of the main thread to join the thread "sub_routine"
The modified version of your code works properly:
#include <stdio.h>
#include <pthread.h>
void *sub_routine(void *p)
{
p = NULL;
printf("This is a sub_routine\n");
return (NULL);
}
int main(int argc, char **argv)
{
void *p;
pthread_t thread;
if (argc < 1)
return (0);
p = argv[1];
pthread_create(&thread, NULL, sub_routine, NULL);
sub_routine(p);
pthread_join(thread, NULL);
return (0);
}
Related
I've been trying to create a chat program in C with threads but it hasn't been working, so I decided to play with threads for a bit first. I'm trying to run a thread that prints "hello world", but it gives me a segmentation fault. I haven't been able to find the root of the problem so I came here. heres the code:
#include <stdio.h>
#include <pthread.h>
void* test(void * arg) {
printf("hello world\n");
return NULL;
}
int main() {
pthread_t test;
pthread_create(&test, NULL, (void *) test, NULL);
pthread_exit(NULL);
return 0;
}
There's probably a stupid reason why it's not working so I hope you guys wont have too much trouble finding it!
Your start routine name and thread id name are the same so I think compiler gets confused when you pass &test. Your code works by changing the thread id name.
#include <stdio.h>
#include <pthread.h>
void* test(void * arg) {
printf("hello world\n");
return NULL;
}
int main() {
pthread_t t;
pthread_create(&t, NULL, (void *) test, NULL);
pthread_exit(NULL);
return 0;
}
void* test(void * arg) { ... }
// vvvv
pthread_t test;
pthread_create(&test, NULL, (void *) test, NULL);
// ^^^^
That pthread_t variable is "hiding" the function name. In other words, you're calling some arbitrary uninitialised value as your function. That's unlikely to end well :-)
What you're doing is really no different to expecting the following program to output 7 (it won't):
#include <stdio.h>
int i = 7;
int main(void) {
int i = 42;
printf("%d\n", i);
return 0;
}
You could solve it simply by renaming your function to testFn, for example.
Hey so I'm trying to create a multithreaded program. The first thread takes in input from std in and stores it in a minheap. The second thread... well for now, all it does is print "sequencer thread works" and nothing else because it doesn't run properly.
Both threads are detached, so they should run simultaneously, and yet for some reason the second thread doesn't run until the first exits. Is it something simple I am overlooking? I'm new to multithreading.
Thanks
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>
#include "MinHeap.h"
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void* readerthread(MinHeap minheap, char eventlist[], char timestamp[])
{
char buffer[100];
char input;
int ret, len, fd;
while(1)
{
char *choice;
choice = malloc(50*sizeof(char));
fgets(choice, 50, stdin);
printf("choice = : %s", choice);
if(checkTimestamp(choice)==0)
{
pthread_mutex_lock(&mutex);
addElement(&minheap, choice);
pthread_mutex_unlock(&mutex);
}
free(choice);
printf( "min of minheap: %s\n", getMin(&minheap));
}
void* sequencerthread()
{
printf("sequencer works\n");
fflush(stdout);
pthread_exit(0);
}
int main(int argc, char *argv[])
{
if (argv < 2)
{
printf("not enough arguments. exiting...\n");
return 1;
}
char timestamp[50];
char event[50];
char eventlist[sizeof(char)+170];
int i;
char nowtimestamp[] = "2400/001/00/00/00";
MinHeap minheap;
initializeMinHeap(&minheap, intCompare, sizeof(char)*50);
strcpy(timestamp, argv[1]);
strcpy(event, argv[2]);
pthread_t ignore1, ignore2;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
pthread_create(&ignore1, &attr, readerthread(minheap, eventlist, nowtimestamp), 0);
pthread_create(&ignore2, &attr, sequencerthread, 0);
pthread_attr_destroy(&attr);
pthread_exit(0);
return (EXIT_SUCCESS);
}
This line is the problem:
pthread_create(&ignore1, &attr, readerthread(minheap, eventlist, nowtimestamp), 0);
You're calling readerthread on the main thread and passing its result to pthread_create. Since readerthread never returns, you never even get to the first call to pthread_create, let alone the second one.
You need to call it like this instead:
pthread_create(&ignore1, &attr, readerthread, &readerthread_args);
where readerthread_args is a struct encapsulating the arguments to pass to readerthread. You'll also need to change readerthread to take a single void * argument, cast it to the type of readerthread_args, and unpack the args.
You should have got a whole bunch of warnings from your compiler. Did you remember to turn them on?
Now this is just a little test, and part of a school assignment. In my code printf is not printing at least to me being able to see it. Is this a result of the thread not functioning? The print line works outside of the thread. Thank you for any help.
I am new to threading in c.
#include<stdio.h>
#include<pthread.h>
#include<string.h>
#include<stdlib.h>
void *threadServer(void *arg)
{
printf("This is the file Name: %s\n", arg);
pthread_exit(0);
}
int main(int argc, char* argv[]){
int i=1;
while(argv[i]!=NULL){
pthread_t thread;
pthread_create(&thread, NULL, threadServer,argv[i]);
i++;
}
In your code, the parent thread of execution that created another thread finishes execution without waiting for its child threads to finish. And threads, unlike processes, once the parent thread terminates, all its child threads of execution terminate as well.
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
void *threadServer(void *arg)
{
printf("This is the file Name: %s\n", (char*)arg);
pthread_exit(0);
}
int main(int argc, char* argv[]){
int i=1;
while(argv[i]!=NULL){
pthread_t thread;
pthread_create(&thread, NULL, threadServer, argv[i]);
i++;
pthread_join(thread, NULL);
}
}
Doing this will allow the thread created to run, until it finishes execution. The pthread_join will wait for the thread to complete its execution and then move ahead.
EDIT
As people did mention in the comments, it is probably worthless trying to spawn a single thread and joining it immediately, making it no better than a single thread of execution. Hence, for the sake of experimentation, the code can be modified as follows:
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
void *threadServer(void *arg)
{
printf("This is the file Name: %s\n", (char*)arg);
}
int main(int argc, char* argv[]){
int i = 1;
pthread_t thread[argc - 1];
while(i < argc)
{
pthread_create(&thread[i-1], NULL, threadServer, argv[i]);
i++;
}
for (i = 0; i < argc - 1; ++i)
{
pthread_join(thread[i], NULL);
}
}
#include <stdio.h>
#include "mythreads.h"
#include <stdlib.h>
#include <pthread.h>
void *
mythread(void *arg) {
printf("%s\n", (char *) arg);
return NULL;
}
int
main(int argc, char *argv[])
{
if (argc != 1) {
fprintf(stderr, "usage: main\n");
exit(1);
}
pthread_t p1, p2;
printf("main: begin\n");
Pthread_create(&p1, NULL, mythread, "A");
Pthread_create(&p2, NULL, mythread, "B");
// join waits for the threads to finish
//Pthread_join(p1, NULL);
//Pthread_join(p2, NULL);
printf("main: end\n");
return 0;
}
This is a code from Remzi Chapter 27. Playing around, I'm curious to know why sometimes on run, I get A printed twice. I know why this is happening, because I haven't included the join statement. Why should skipping join cause this?
My output:
shubham#HP:~/OS/Code-Threads-Intro$ ./a.out
main: begin
A
main: end
B
shubham#HP:~/OS/Code-Threads-Intro$ ./a.out
main: begin
A
main: end
B
shubham#HP:~/OS/Code-Threads-Intro$ ./a.out
main: begin
main: end
A
shubham#HP:~/OS/Code-Threads-Intro$ ./a.out
main: begin
main: end
B
A
A
Removing the call the pthread_join() should not cause "A" to be printed twice. (Barring a bug in the implementation.)
But since your fprintf() calls share the same FILE * structure, they may not be not multithread-safe. How and why they could print "A" twice is dependent upon the implementation details of your system's fprintf() function.
This is my code, I compiled it with:
gcc thread.c -lpthread
It didn't print any error or warning. But when I run it, the program doesn't print anything.
Platform: Ubuntu 11.10 64 bit gcc 4.6.1
Exit status :0
When I debug it, I found it prints hello as I expected.
This is my code:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
void *loopPrint(void *ptr)
{
char *p = (char *)ptr;
while (1)
{
printf("%s\n", p);
}
}
void *pClock(void *ptr)
{
sleep(3);
exit(0);
}
int main()
{
pthread_t showMsg, clock;
int main_pth, wait_pth;
char *msg = "Hello";
main_pth = pthread_create(&showMsg, NULL, loopPrint, (void *)msg);
wait_pth = pthread_create(&clock, NULL, pClock, NULL);
pthread_join(main_pth, NULL);
pthread_join(wait_pth, NULL);
return 0;
}
pthread_join(main_pth, NULL);
This is wrong, pthread_join takes a pthread_t as an argument. Replace with:
pthread_join(showMsg, NULL);
(Same for the other one.)
And do check the return values of these calls, they can and do fail.
And BTW, you're missing #include <unistd.h> for the sleep call.
main_pth etc is the error return of pthread_create and not the thread id. Wait ("join") for showMsg and clock.