POSIX parent/child threads not sharing data - c

One final question for the evening. I have a homework question that I cannot seem to solve, and after spending the better part of the night on it, I'll ask it here.
The problem is a program that is to calculate the Fibonacci sequence given an integer input at the command line (./foo.out 15, for example, and it will calculate the first 15 Fibonacci numbers). The additional parameters are as follows:
1.) It must use two POSIX threads, a parent thread and a child thread.
2.) It must share data (an array) between them.
Currently, the function is breaking when program control passes back to the parent thread. All I am getting is a completely non-descriptive segfault. As can be seen below, I have it outputting at every possible change in control.
Code:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
void *fibonacci(void *param, int numbers[]);
void *runner(void *param);
int main(int argc, char *argv[])
{
pthread_t tid;
pthread_attr_t attr;
if ( argc != 2)
{
fprintf(stderr, "Usage: 426.out <integer value> \n");
return -1;
}
if (atoi(argv[1]) < 0)
{
fprintf(stderr, "Argument must be non-negative\n");
return -2;
}
pthread_attr_init(&attr);
pthread_create(&tid, &attr, runner, argv[1]);
pthread_join(tid,NULL);
return 0;
}
void *fibonacci(void *param, int numbers[])
{
int it, IT_MAX;
printf("Entering Child Thread:\n");
IT_MAX = atoi(param);
numbers[0] = 0;
numbers[1] = 1;
for (it = 2; it < IT_MAX; ++it)
{
numbers[it] = (numbers[it - 1] + numbers[it - 2]);
}
for (it = 0; it < IT_MAX; ++it)
{
printf("%d\n", numbers[it]);
}
printf("Exiting Child Function.\n");
}
void *runner(void *param)
{
int it, IT_MAX;
int numbers[IT_MAX];
pthread_t tid;
pthread_attr_t attr;
printf("Entering Parent Thread:\n");
pthread_attr_init(&attr);
pthread_create(&tid, &attr, fibonacci(param, numbers), NULL);
pthread_join(tid, NULL);
IT_MAX = atoi(param);
for (it = 0; it < IT_MAX; it++)
{
printf("%d\n", numbers[it]); // I suspect the program breaks here
// It produces a segfault rather than this
}
printf("Leaving Parent Thread\n");
}
The question I have, if it is not clear from above, is what am I doing wrong. I am using gcc, and have been using the -Wall -Werror and -lpthread. -Werror keeps throwing "Control Structure going to end of non-void function", but nothing has anything to say about what can be causing the segfault. As before, I looked for the last hour for a question or article that addresses this, so if this is a dupe, please point me to the question or article in which it is addressed. Thanks to anyone in advance for their help.

One of your problems is in this line:
pthread_create(&tid, &attr, fibonacci(param, numbers), NULL);
Instead of starting a thread with the fibonacci() function, this calls the fibbonacci() function in the current thread and passes the result to pthread_create() as the thread start function. fibonacci() doesn't return a function pointer, so this new thread will crash the program.
You need to just pass fibonacci as the third parameter.
Futhermore, fibonacci() must be declared as void *fibonacci(void *) in order to be used as a thread start function. If you want to pass two parameters, you'll need to place them into a struct and pass a pointer to that.
This pair of lines is also problematic:
int it, IT_MAX;
int numbers[IT_MAX];
IT_MAX is an uninitialised variable, and you use it here to define the size of the numbers[] array. That could also be leading to your crash.

This line
pthread_create(&tid, &attr, fibonacci(param, numbers), NULL);
does not pass the address of fibonacci() to pthread_create() but calls fibonacci(param, numbers)and passes the result returned to pthread_create() as 3rd argument.

Related

Is it possible to create threads in multiple files to be executed in main file?

I have the following structure to want to interact with a sorter (infinite loop) and networker (infinite loop) on 2 separate threads. The threads are generated in each of their respective files instead of the main file. Are there any issues with this?
main.c
int main(void {
network();
sorter();
}
sort.c // creates random array then sorts them in a continuous while loop (never ending)
void sorter() {
int r1 = pthread_create(&thread1, NULL, (void *) &sorter, NULL);
pthread_join(thread1, NULL);
}
int* getArray() { ... }
int getElement() { ... }
network.c
void network() {
int r2 = pthread_create(&thread2, NULL, (void *) &startNetwork, NULL);
pthread_join(thread2, NULL);
}
void startNetwork() {
int sockfd, portno, optval, n;
socklen_t adSize;
struct sockaddr_in servAd, clientAd;
...
while(1) {
//receive packet
int *arr = getArray();
// send packets
// or receive packet that has a command to get array
}
}
Is it possible to have the threads structured like that? Will my main file freeze because the thread is not being created in the main file? Is there a better way to do this?
The main issues with sorter() are (1) that it won't return until the thread function returns, and (2) the thread function is sorter(), so you have an indefinite loop. This is likely a problem with trying to abstract your code into the question. There are nitty-gritty details to fix up like the types of the functions, etc.
The issues with network() might be similar or different; you've not shown the function you call from main(), so it is not clear what you intend. The code in networker() is not good; it makes pthread_create() call a function with an incorrect signature — thread functions should have the signature void *function(void *arg);.
However, in general, there is no problem with starting different threads in code from different source files. If the threads are not detached — if you're going to join them — then you'll need to make the pthread_t initialized by pthread_create() available for the code that manages the joining — possibly because they're in global variables or part of a global array, or possibly because you provide functional access to private data stored in the separate source files.
So, you might have:
network.c
static pthread_t thread2;
static void *network_thread(void *arg);
void network(void)
{
if (pthread_create(&thread2, NULL, network_thread, NULL) != 0)
…handle error…
}
void network_join(void)
{
void *vp = 0;
if (pthread_join(&thread2, &vp) != 0)
…report error…
…maybe use the return value in vp…
}
sorter.c
static pthread_t thread1;
static void *sorter_thread(void *arg);
void sorter(void)
{
if (pthread_create(&thread1, NULL, sorter_thread, NULL) != 0)
…handle error…
}
void sorter_join(void)
{
void *vp = 0;
if (pthread_join(&thread1, &vp) != 0)
…handle error…
…maybe use value in vp…
}
main.c
#include "sorter.h"
#include "network.h"
int main(void)
{
network();
sorter();
network_join();
sorter_join();
return 0;
}
You would probably build checks into network_join() and sorter_join() such that if you've not already called network() or sorter(), the code won't try to join an invalid thread.
Are there any issues with this?
It looks like maybe you do not understand what pthread_join(thread1) does. It does nothing, except wait until thread1 is finished. But you said that the network thread and the sorter thread are meant to run forever, so that's going to be a long wait:
For future reference, pthread_join() is meant to be used like this:
pthread_create(&thread1, attrs, f, arg);
doSomethingElse(...);
pthread_join(thread1, NULL);
doOtherStuff(...);
The original thread starts the new thread, and then it does something else while the new thread is calling f(arg). Then, after the f(arg) call and the doSomethingElse(...) call have both completed, the original thread goes on to doOtherStuff(...).

How to use Multithreading in C? [duplicate]

This question already has answers here:
How to "multithread" C code
(13 answers)
Closed 3 years ago.
This is my first contact with c and Multithreading.
I look for an example how to use it in Basic.
This is what I want to to parallel:
PseudoCode that should run on different Threads
Code1
int main(){
int i =1000;
while(i>0){
i--;
}
}
Code2
int main(){
int x =0;
if(i%5){
x++;
}
}
I also didn't know how to pass Objects, maybe someone can explaine this too.
Please use only lowercase in C to declaring variables and functions
as struct,typeof,sizeof,int,char,void,for,while,etc....
EDIT:
Sorry for not to understand "I thought you need help to do that code in C"
Now i know that you want multi-threading functions to do two jobs or more at the same time without waiting for other to finish.
Okay, to do that you have to
include pthread.h which means POSIX Thread
Note: you should notice from this name that this library for Linux OS only
and you compile it with gcc compiler
declare variable pthread to for example: tid in your main() as the most popular name
Create your function in void *() and type stuff whatever it does then create your thread in main() and assign it your function through that code:
pthread_create(&tid, NULL, MyThread, NULL);
pthread_create() arguments:
A pointer to a pthread_t structure that we created to fill it with the upcoming arguments.
A pointer to a pthread_attr_t with parameters for the thread. You can safely just pass NULL most of the time.
Note: The pthread_attr_t > "arg 2" should be treated as opaque: any access to
the object other than via pthreads functions is nonportable and
produces undefined results.
Take the function that you created as thread and shall be with no return and
points to >> void, that's why we created void *()
Note: Type only the name of function without (), you will know why in the next argument
Here you passing your arguments to your function!, if there's no arguments just pass NULL
Example Code:
#include <stdio.h>
#include <pthread.h>
int i=0,x=0; //Initialize our variables
void *MyThread(void *ANYarg) //arguments must be a pointers to point from `pthread_create` with `NULL` if no need
{
while(1) //background thread
{
i++;
x++;
}
return NULL;
}
int main()
{
char *input;
pthread_t tid; //Declare a thread
pthread_create(&tid, NULL, MyThread, NULL); //Create the thread
while(1) //Printing thread , Uncover increamting of variables
{
scanf("%s",&input); //whenever you input a value
printf("i: %d, x: %d\n",i,x);//will print the i,x values now
}
return 0;
}
Note: You should at least create one pointer variable specifically to your thread function cause fourth argument of pthread_create() need at least one to pass the NULL value
You can wait for an thread to finish instead of doing work at the same time through that code line:
pthread_join(tid, NULL);
Should return 0 when success
An Example:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *MyCoolthread(void *vargp)
{
printf("Yes..see me printing success after 3 seconds \n");
sleep(3);
printf("Success! \n");
return NULL;
}
int main()
{
pthread_t tid;
printf("Hello, are you there? \n");
sleep(1);
pthread_create(&tid, NULL, MyCoolthread, NULL);
pthread_join(tid, NULL);
printf("Yup i see!\n");
return 0;
}
Try to comment pthread_join(tid, NULL); with // to see what happens
and to terminate your thread is through code line:
pthread_exit(&tid);
Doesn't return to its caller any value
Edit: I noticed now that you use windows so i advice you to dual boot with Ubuntu instead if you really interested in C
otherwise you can use multi-threading in windows.h header that called winapi library but i'm not expert in so you can find an simple example here and you should mentioned in your post that you want for windows by the way you can edit to improve it
I tried my best to get it clear, hope it helps.

Thread not printing out in correct order

I'm fairly new to threads in C. For this program I need to declare a thread which I pass in a for loop thats meant to print out the printfs from the thread.
I can't seem to get it to print in correct order. Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NUM_THREADS 16
void *thread(void *thread_id) {
int id = *((int *) thread_id);
printf("Hello from thread %d\n", id);
return NULL;
}
int main() {
pthread_t threads[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++) {
int code = pthread_create(&threads[i], NULL, thread, &i);
if (code != 0) {
fprintf(stderr, "pthread_create failed!\n");
return EXIT_FAILURE;
}
}
return EXIT_SUCCESS;
}
//gcc -o main main.c -lpthread
That's the classic example of understanding multi-threading.
The threads are running concurrently, scheduled by OS scheduler.
There is no such thing as "correct order" when we are talking about running in parallel.
Also, there is such thing as buffers flushing for stdout output. Means, when you "printf" something, it is not promised it will happen immediately, but after reaching some buffer limit/timeout.
Also, if you want to do the work in the "correct order", means wait until the first thread finishes it's work before staring next one, consider using "join":
http://man7.org/linux/man-pages/man3/pthread_join.3.html
UPD:
passing pointer to thread_id is also incorrect in this case, as a thread may print id that doesn't belong to him (thanks Kevin)

Main() thread id is different after creating another thread

I've been reading and learning about POSIX threads, and tried to write some simple codes to understand it better.
#include <stdio.h> /* standard I/O routines */
#include <pthread.h> /* pthread functions and data structures */
/* function to be executed by the new thread */
void* PrintHello(void* data)
{
pthread_t tid = (pthread_t)data;
printf("Hello from new thread %d - got %d\n", pthread_self(), tid);
pthread_exit(NULL); /* terminate the thread */
}
int main(int argc, char* argv[])
{
int rc; /* return value */
pthread_t thread_id;
int tid;
thread_id = pthread_self();
printf("FLAG = %d ", thread_id);
/* create a new thread that will execute 'PrintHello' */
rc = pthread_create(&thread_id, NULL, PrintHello, (void*)thread_id);
if(rc) /* could not create thread */
{
printf("\n ERROR: return code from pthread_create is %u \n", rc);
exit(1);
}
printf("\n Created new thread (%d) ... \n", thread_id);
pthread_exit(NULL); /* terminate the thread */
}
For this code I get the following output:
FLAG = 363480832
Created new thread (355198720) ...
Hello from new thread 355198720 - got 363480832
What is bothering me is why thread_id which is 363480832, becomes 355198720, same as thread_id of a function that was called from main (PrintHello()). I assumed that thread id doesn't change throughout the program execution. Or is it something inside the function that changes it?
If you're doing anything with a pthread_t other than passing it to a function that takes one, you're doing something wrong. Only the pthreads API knows how to use a pthread_t correctly. They can have any internal structure that's convenient for the implementation.
Being a C language construct, pthread_t behaves more like char *. The necessary language constructs to make it behave like std::string don't exist. So you have to treat it like char *.
A char * contains a string somehow, but you have to understand its implementation to get that value out. Consider:
char *j = "hello";
char *k = strdup (j);
if (j == k)
printf ("This won't happen\n");
printf ("%d\n", j);
printf ("%d\n", k); // these won't be equal
You can't compare char *'s with == to see if they refer to the same string. And if you print out j and k, you'll get different values.
Similarly, a pthread_t refers to one particular thread somehow. But you have to understand how to get the value out. Two pthread_ts can have different apparent values but still refer to the same thread just as two char *s can have different apparent values but still refer to the same string.
Just as you compare two char *'s with strcmp if you want to tell if they refer to the same string value, you compare two pthread_ts with pthread_equal to tell if they refer to the same thread.
So this line of code makes no sense:
printf("FLAG = %d ", thread_id);
A pthread_t is not an integer and you can't print it with a %d format specifier. POSIX has no printable thread IDs. If you want one, you need to code one (perhaps using pthread_getspecific).
In C, arguments are passed by value. In particular, the argument (void *)thread_id is an expression that's evaluated before calling pthread_create, so the fact that pthread_create writes to thread_id as a result of &thread_id being passed as the first argument is irrelevant. If you were instead passing &thread_id rather than (void *)thread_id as the argument to the new thread start function, and dereferencing it there, then you may see the effects you want; however, it's not clear to me that pthread_create's writing of the new thread id via its first argument is required to take place before the new thread starts, so there is probably a data race if you do it that way.
Further, note that David's answer is also correct. It's invalid to print thread ids this way since they are formally an opaque type.
In this line:
rc = pthread_create(&thread_id, NULL, PrintHello, (void*)thread_id);
as the manual says, pthread_create() shall store the ID of the created thread in the location referenced by thread_id. In this example, it would be modified to 355198720, which is the tid of new thread PrintHello().
Besides, it may be better to change the argument for PrintHello to:
rc = pthread_create(&thread_id, NULL, PrintHello, (void*)&thread_id);
and in PrintHello(), it would be:
void* PrintHello(void* data)
{
pthread_t tid = (pthread_t)(*data);
...
}

How to pass one or multiple variables to a newly created thread?

I'm learning about threads now. I'm wondering if it is possible to pass a variable to my thread. My assignement is to create a thread and assign a number (a name if you will) to each thread and print the number every 100ms. my current program is as below :
#define PCHECK(sts,msg) if((sts)!=0){printf("error : %s\n",msg); exit(EXIT_FAILURE)}
#define NB_THREAD 5
void* do_nothing(void* data)
{
int i;
//printf("creation thread %d",(int)data);
while(1)
{
usleep(100000);
printf("thread number : %d \n",data);
}
i = 0;
pthread_exit(NULL);
//exit(EXIT_SUCCESS);
}
int main(int argc, char *argv[])
{
int pid, j, status;
pthread_t thread;
int * res;
int stat;
for (j = 0; j < NB_THREAD; j++)
{
stat = pthread_create(&thread, NULL, do_nothing, (void *) j );
if (stat !=0)
{
perror ("pthread_create()");
}
}
for (j = 0; j < NB_THREAD; j++)
{
pthread_join(thread, (void **) &res );
}
return EXIT_SUCCESS;
}
for the moment the only number getting printed is 0 (the value of data). Can someone point out where did i went wrong thanks :)
Here are some good examples of how to pass arguments to pthreads
[1] https://computing.llnl.gov/tutorials/pthreads/#PassingArguments
I suspect that your problem might be that your running this on a 64-bit system that uses 32-bit int types. So data is a 64-bit void* type but in your thread function you're printing it out as a 32-bit int:
// example assumes that this thread instance was started by
// pthread_create(&thread, NULL, do_nothing, (void *) j ) when
// j == 1
printf("thread number : %d \n",data);
^ ^
| +-------- passing a 64-bit pointer 0x00000000.00000001
|
+---------------- treats the pointer argument as a 32-bit int and
happens to only see the all-zero 32-bits
I suspect that you'll get the output you expect if you change the printf() to:
printf("thread number : %d \n", (int) data);
As a general rule, when writing thread functions I think it's a good idea to have the first actions of the thread function be to convert the data item passed to the thread function to the type that was actually passed to pthread_create():
void* do_nothing(void* data)
{
int id = (int) data; // `pthread_create()` was passed an `int`
// `data` is not used again after this point
// ...
}
A few other points
if you pass an actual pointer to data to the thread function, make sure that each thread gets their own separate copy (unless the data is supposed to be the same instance for each thread, which is possible but uncommon).
if you're spinning up multiple threads you either need to keep each pthread_t object returned by pthread_create() (in an array, maybe) so you can join on them later, or you need to call pthread_join()/pthread_detach() before reusing the pthread_t object so that the system can clean up any resources it has allocated for that thread when the thread finished running. In the example as posted that might not matter much because the threads will run forever (or until something kills the process). The pthread_join() call you have will never complete successfully.
But the following code is destined to break when you change things so the thread function stops after some amount of time:
for (j = 0; j < NB_THREAD; j++)
{
pthread_join(thread, (void **) &res );
}
Because thread only has the pthread_t for the last thread created, once it successfully joins it's not valid to use any more. The next loop iteration will try to join a thread that's already been joined and is no longer valid.

Resources