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.
Related
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)
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);
...
}
I am using pthread_t to print out the pid of a thread that I manually create in C. However, I print it before I create my new thread (passing it by ref as a parameter) and it prints a different value (presumably the thread that my main function is executing on). I would have expected it to default to be 0 or unitialised. Any ideas?
Thanks,
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
struct thread_info { /* Used as argument to thread_start() */
pthread_t thread_id;/* ID returned by pthread_create() */
};
static void *thread_1_start(void *arg) {
struct thread_info *myInfo = arg;
printf("Started thread id: %d\n", myInfo->thread_id);
pthread_exit(0);
}
int main() {
struct thread_info tinfo;
int s;
printf("Main thread id: %d\n", tinfo.thread_id);
s = pthread_create(&tinfo.thread_id,
NULL, // was address of attr, error as this was not initialised.
&thread_1_start,
&tinfo);
pthread_join(tinfo.thread_id,NULL);
}
Actual output:
Main thread id: 244580352
Started thread id: 245325824
Expected output:
Main thread id: // 0 or undefined
Started thread id: 245325824
The problem is you are not initialising tinfo structure.
In local variables (as opposed to global/heap variables), values are not initialised in C Programming Language.
So, if you do something like:
int c;
printf("%d", c);
You should not expect a coherent value since it will depend on what's on that memory location in that moment.
You need to initialize tinfo variable. Using memset or assigning tinfo.thread_id = 0 explicitly.
There is no thread-specific logic to initialize tinfo; it is just a regular C struct. It will have whatever data was in that memory address at the initialization. You need to explicitly initialize it.
You can initialize the value to zero by:
struct thread_info tinfo = { 0 };
Declare struct thread_info tinfo; global and see what happens.
There's a number of important things you need to know.
First, pthread_t is opaque. You can't reliably print it with printf because nowhere in the POSIX standard is pthread_t specified as beinban into, struct or whatever. By definition you can't print it and get a meaningful output.
Second, if a thread needs to know it's pthread_t ID it can call pthread_self(). You don't need to tell the thread what its ID is externally like you're trying to do.
But never mind that! The condition you describe where the printed output is close to what you're expecting is because you have a race between the thread printing out and pthread_create assigning the pthread_t to thread_info.thread_id, and due to pthread_t actually being an integer type on Linux (so it's likely that they're allocated sequentially, and you're just getting an old value).
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.
In the call pthread_create(&id, NULL, &start_routine, arg), is the thread id guaranteed to be written to id before start_routine starts running? The manpages are clear that the start_routine may but will not necessarily begin executing before the call to pthread_create returns, but they are silent on when the thread id gets written back to the passed thread argument.
My specific case is that I have a wrapper around pthread_create:
int mk_thread(pthread_t *id) {
pthread_t tid;
pthread_create(&tid,NULL,ThreadStart,NULL);
if (id == NULL) {
pthread_detach(tid);
} else {
*id=lid;
}
}
which can obviously run the start routine before writing back. I changed it to
int mk_thread(pthread_t *id) {
pthread_t tid,tidPtr=id?id:&tid;
pthread_create(tidPtr,NULL,ThreadStart,NULL);
if (id == NULL) {
pthread_detach(tid);
}
}
This rewrite is much more stable in practice, but is it actually a fix or just a smaller window for the race condition?
The thread id is definitely written before pthread_create returns. If you think about it, it would be impossible for pthread_create to work any other way. It could not delegate writing the thread id to the new thread, because the pthread_t variable might be out of scope by the time the new thread runs.
The relevant text is:
Upon successful completion, pthread_create() shall store the ID of the created thread in the location referenced by thread.
(From http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_create.html) Note that it says "on successful completion" of the function, not "at an indeterminate time after successful completion".
The more interesting question, and I'm unclear on this one, is whether pthread_create must have finished writing the thread id to its destination before the new thread start function begins, i.e. whether the new thread can immediately see its own thread id, e.g. if it's to be stored in a global variable. I suspect the answer is no.
Edit: Upon rereading your question, it seems like you might really have been asking about this latter, more interesting question. In any case, there's no reason for the new thread's start function to use the thread-id written out by pthread_create. Your new thread can (and should) just use pthread_self to get its own thread id.
I believe that nothing in the spec requires pthread_create to assign its output parameter pthread_t *thread before code in start_routine begins to execute.
As a matter of practicality, the following program succeeds on many pthreads implementations (freebsd8 i386 and debian gnu/linux amd64) but fails on one of interest to me (debian/kfreebsd9 amd64):
#include <pthread.h>
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
pthread_t th;
void *asserter(void* unused) {
pthread_t self = pthread_self(), th_=th;
printf("th=%jd self=%jd\n", (intmax_t)th_, (intmax_t)self);
assert(pthread_equal(th_, self));
}
int main() {
int i;
for(i=0; i<1000; i++) {
pthread_create(&th, NULL, asserter, NULL);
pthread_join(th, NULL);
}
return 0;
}
that said, I am not sure I understand how this detail of behavior is relevant to the two code alternatives you offer in the original question. Though it occurs to me that if pthread_create writes other values to *thread during its execution, and you're using the value of *id in the other thread, it could be relevant. The standard does not specify that no other 'intermediate' values are written to *thread during successful execution of pthread_create.