I just cut and paste the code, why the result is different?
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.
Try putting a sleep or usleep in your thread code. (Like within the for loops of your first example.) That will force that thread to give up some CPU time to other threads. It may or may not help you get the unpredictable result you are looking for.
Here's an example using usleep. It gives me a different result each time I run it.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
void thread(void)
{
int i;
for(i=0;i< 3;i++)
{
printf("This is a pthread.\n");
usleep(500);
}
}
int main(void)
{
pthread_t id;
int i,ret;
ret=pthread_create(&id,NULL,(void *) thread,NULL);
if(ret!=0)
{
printf ("Create pthread error!\n");
exit (1);
}
for(i=0;i< 3;i++)
{
printf("This is the main process.\n");
usleep(500);
}
pthread_join(id,NULL);
return (0);
}
Results:
Code:
$ ./threadtest
This is the main process.
This is a pthread.
This is the main process.
This is a pthread.
This is the main process.
This is a pthread.
$ ./threadtest
This is a pthread.
This is the main process.
This is the main process.
This is a pthread.
This is the main process.
This is a pthread.
You can probably play with the sleep time a bit to see what you get.
if you want to see how this can really happen....
you'd again get a same output all the time...but if you put a
statement like :
Code:
if (pthread_self() == thread1)
sleep(1);
you'd have to make thread1 a global variable tho...
you'll get the "world hello". ..this proves that while your 1st thread is doing a lot more than just printing stuff...the second thread just prints....so your second thread gets to print and thus u get world hello..always....
tho the o/p is same always...it does show that thread1 is not allowed to complete its sleep and print before 2nd thread can run...which wouldnt happen if locks were used...
What both deiussum, shishir, and I are trying to allude to is there must be something to cause the system to want to switch threads.
Linux (and basically all OS's) don't just switch threads for the hell of it. Switching threads wastes time so you want to do it as little as possible. They will happily run a thread from start to completion providing something doesn't happen to make it do otherwise.
There are only three things I can think of that can happen: The thread's quanta runs out (basically means the particular thread has been a CPU hog for two long), a "slow" system call is made (something that the thread would have to wait for, sleep/usleep are good examples), an interrupt occurs and triggers a context switch for some reason.
Neither of the two pieces of code you originally submitted have any chance of the first two things happening (quanta or system calls causing a context switch). Without getting into to much detail, the interrupt causing a context switch option is theoretically possible, but rarely if ever happens. If your interested I can explain this to you in more detail, but it involves pretty specific information dealing with how the kernel handles syscalls, interrupt handers, and things of that nature... more then most people care to know.
As such, you'd almost expect the result would always be the same, though theoretically it could end up changing and still be correct.
Thank you all!!
I kinnda got what you guys say.
This is a great forum. Fast response and helpful people/materials.
A good place to start learning linux/programming.
The ideas you guys provided are excellent.
while (i>0)
{
printf("This is a pthread. %d\n", i);
i--;
sleep(1);
}
}
int main(void)
{
pthread_t id;
int ret;
ret=pthread_create(&id,NULL,(void *) thread,NULL);
if(ret!=0)
{
printf ("Create pthread error!\n");
exit (1);
}
while (i>0)
{
printf("This is the main process. %d\n", i);
i--;
sleep(1);
}
pthread_join(id,NULL);
return (0);
}
-------code ends------------
output is:
This is the main process. 5
This is a pthread. 4
This is the main process. 3
This is a pthread. 2
This is the main process. 1
please look at the last value of each line. they're decrement by 1 because I am updateing this global variable each time any of the thread is running. Since the thread are running concurrently, why isn't there any thing "strange" happens? ie: the result can be:
This is the main process. 5
This is a pthread. 4
This is the main process. 4
This is a pthread. 3
This is the main process. 1.
or why the system didn't freeze when the situation both threads are undating the global variable (I) at the same time?
I read about pthread_join(), it says the threads will wait until the other thread finishes first before it starts. So it will never have the "Strange" situation I mentioned?
But for my project, I want this situation to happen. Then later I can apply "Mutex" to protect the critical section (global variable i) to prevent both threads updating the global variable at the same time.
anybody knows the answer please help me.
Threads don't always run concurrently, they just appear to... On a single cpu box they still have to take turns in the physical cpu...
Multi-cpus can run separate threads simultaneously, hence need for locking (mutexes in your case).
Using locks anyway forces you to construct code that doesn't assume var has not changed value between statements.
Here's a good explanation: http://perl.active-venture.com/pod/perlthrtut.html
Well part of the point is you can't force the "strange" situation to happen. if you have 1 cpu, and your threads are doing relatively little (as they are in your case) it is very likely they will run and finish in exactly the order they were created in. You can't force them to run out of order unless you put locking in to make it happen that way.
In the case of 1 cpu (ok... on hyperthreading processors... aka newer Intel Xeon's and Pentium 4 HT's this is a bit different) you will only ever have one thread or process executing at a given time. You can't run two threads simultaneously if you only have 1 cpu to do the processing. As a result generally things will be executed in order. As I said earlier, there is no quanta situation your running into because all of your threads will execute so quickly.
I have prepared a very quick and dirt program that shows some randomness with threads... at least it appears to, I tossed this together in about two seconds so forgive me if it isn't perfect.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <limits.h>
void thread_example( void *ptr );
int main()
{
pthread_t thread1, thread2;
int i, ret, tval1,tval2;
tval1 = 1;
tval2 = 2;
ret = pthread_create( &thread1, NULL,
(void*)&thread_example, (void*) &tval1);
if (ret != 0) {
printf ("pthread 1 create error\n");
}
ret = pthread_create(&thread2, NULL,
(void*)&thread_example, (void*) &tval2);
if (ret != 0) {
printf ("pthread 2 create error\n");
}
for (i=0;i<UINT_MAX;i++) {
if ((i % 1024) == 0) {
printf ("Main, Count = %u\n",i);
usleep(500);
}
}
pthread_join(thread1,NULL);
pthread_join(thread2,NULL);
exit(0);
}
void thread_example( void *ptr )
{
unsigned int i,*tnum = (unsigned int *) ptr;
for (i=0;i<UINT_MAX;i++) {
if ((i % 1024) == 0) {
printf ("Thread %u, Count = %u\n",*tnum,i);
usleep(1000 / *tnum);
}
}
}
Beware... this code will take quite some time to execute to completion. You might not want to use UINT_MAX in those for loops if you want to actually see it run to completion
This was compiled with gcc -Wall -o test test.c under Mac OS 10.3.8 (GCC 3.3 20030304). Keep in mine of course under linux you must add -lpthread to compile this... Mac OS automatically links in the posix's thread library.
Originally posted by jtshaw Well part of the point is you can't force the "strange" situation to happen. if you have 1 cpu, and your threads are doing relatively little (as they are in your case) it is very likely they will run and finish in exactly the order they were created in. You can't force them to run out of order unless you put locking in to make it happen that way.
In the case of 1 cpu (ok... on hyperthreading processors... aka newer Intel Xeon's and Pentium 4 HT's this is a bit different) you will only ever have one thread or process executing at a given time. You can't run two threads simultaneously if you only have 1 cpu to do the processing. As a result generally things will be executed in order. As I said earlier, there is no quanta situation your running into because all of your threads will execute so quickly.
I have prepared a very quick and dirt program that shows some randomness with threads... at least it appears to, I tossed this together in about two seconds so forgive me if it isn't perfect.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <limits.h>
void thread_example( void *ptr );
int main()
{
pthread_t thread1, thread2;
int i, ret, tval1,tval2;
tval1 = 1;
tval2 = 2;
ret = pthread_create( &thread1, NULL,
(void*)&thread_example, (void*) &tval1);
if (ret != 0) {
printf ("pthread 1 create error\n");
}
ret = pthread_create(&thread2, NULL,
(void*)&thread_example, (void*) &tval2);
if (ret != 0) {
printf ("pthread 2 create error\n");
}
for (i=0;i<UINT_MAX;i++) {
if ((i % 1024) == 0) {
printf ("Main, Count = %u\n",i);
usleep(500);
}
}
pthread_join(thread1,NULL);
pthread_join(thread2,NULL);
exit(0);
}
void thread_example( void *ptr )
{
unsigned int i,*tnum = (unsigned int *) ptr;
for (i=0;i<UINT_MAX;i++) {
if ((i % 1024) == 0) {
printf ("Thread %u, Count = %u\n",*tnum,i);
usleep(1000 / *tnum);
}
}
}
Beware... this code will take quite some time to execute to completion. You might not want to use UINT_MAX in those for loops if you want to actually see it run to completion
This was compiled with gcc -Wall -o test test.c under Mac OS 10.3.8 (GCC 3.3 20030304). Keep in mine of course under linux you must add -lpthread to compile this... Mac OS automatically links in the posix's thread library.
Okay, excellent!! I got what you said. And thank you all for helping me. The time quanta plays a very significant role in running threads. And I will apply your idea to my situation. And some others asked me to use pthread_yield() to do that as well. Anyways, thank you so much.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.