ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Hey all,
Relearning some c coding and testing out threading for the first time - wrote what should be a simple program, however it does not do what i expected. I want it to run freddi thread, then main thread symmetrically however my output is inconsistent at best.
here's the test code:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define _memory -5
#define _badthread -6
#define _badyield -7
#define _badlock -8
#define _badunlock -9
#define throw(R,E) if(R)return E
#define require(R,E) do{if(R){print_error(E);exit(0);}}while(0)
void print_error(long err)
{
switch(err)
{
case _memory:
fprintf(stdout,"error allocation failed\n");
break;
case _badthread:
fprintf(stdout,"error bad thread\n");
break;
case _badyield:
fprintf(stdout,"error bad yield\n");
break;
case _badlock:
fprintf(stdout,"error bad lock\n");
break;
case _badunlock:
fprintf(stdout,"error bad unlock\n");
break;
}
}
void *freddi()
{
while(1)
{
fprintf(stdout,"@");
}
return 0;
}
int main(int argc, char *argv[])
{
#define log_error(T,E) fprintf(stdout,"thread %d: ",T);print_error(E)
pthread_t freddy; void **ret;
require(!(ret = malloc(sizeof(void *))),_memory);
require(pthread_create(&freddy,0,&freddi,0),_badthread);
while(1)
{
fprintf(stdout,"*");
}
pthread_join(freddy,ret);
fprintf(stdout,"\n");
if(ret)print_error((long)(*ret));
free(ret);
return 0;
}
This is some sample output I'm getting (its very inconsistent)
Threads can run when(in any order) they want. You have to checkout how threads should wait for each other. Search for thread, wait, join, synchronization, timeout etc
A more practical solution in this situation might be a pthread barrier, which will block all threads that pthread_barrier_wait until the Nth "waiter". You also shouldn't count on buffered output working well between threads.
Kevin Barry
thanks ta0kira,
ill have to look into the pthread barrier (is this like a mutex?).
Could you recommend any reading on the buffered output - I don't quite understand the importance in the threaded context
I generally have the following analogy in mind wrt pthread barriers. You set its "size" N when you initialize it, which means that it takes the effort of N threads to "break it down". Sort of like a wall that prevents passing until N people arrive to push it over. Or you could say that it releases every time k%N==0 with k being the cumulative number of pthread_barrier_wait calls.
write is atomic in many cases (dependent on the underlying device); however, fprintf isn't (as far as I know.) That means if two threads are writing to the output stream at once the output might end up interleaved. In general this should not happen with write for "reasonable" output sizes (<4096 is probably a safe guess.) I don't know if there are any good references regarding how buffered output works, but basically when you print to a FILE* the data is appended to a buffer within the process and when certain conditions are met (e.g. '\n' is printed) it will write some/all of the buffered data.
Kevin Barry
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.