LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 02-15-2005, 02:16 PM   #16
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 32

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.

Last edited by deiussum; 02-15-2005 at 02:23 PM.
 
Old 02-15-2005, 02:25 PM   #17
shishir
Member
 
Registered: Jul 2003
Location: bangalore . india
Distribution: openSUSE 10.3
Posts: 251

Rep: Reputation: 33
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...
 
Old 02-15-2005, 02:39 PM   #18
jtshaw
Senior Member
 
Registered: Nov 2000
Location: Seattle, WA USA
Distribution: Ubuntu @ Home, RHEL @ Work
Posts: 3,892
Blog Entries: 1

Rep: Reputation: 67
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.

Last edited by jtshaw; 02-15-2005 at 02:41 PM.
 
Old 02-15-2005, 10:03 PM   #19
keiwu
Member
 
Registered: Feb 2005
Posts: 77

Original Poster
Rep: Reputation: 15
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.
 
Old 02-15-2005, 10:51 PM   #20
keiwu
Member
 
Registered: Feb 2005
Posts: 77

Original Poster
Rep: Reputation: 15
This is the modified code after listen to your ideas. (but my problem hasn't been solved yet)

----code starts-------
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

int i=5;

void thread(void)
{

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.
 
Old 02-16-2005, 09:52 PM   #21
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,359

Rep: Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751
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
 
Old 02-16-2005, 10:48 PM   #22
jtshaw
Senior Member
 
Registered: Nov 2000
Location: Seattle, WA USA
Distribution: Ubuntu @ Home, RHEL @ Work
Posts: 3,892
Blog Entries: 1

Rep: Reputation: 67
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

Example output:
Code:
Main, Count = 2963456
Thread 1, Count = 1776640
Thread 2, Count = 2959360
Main, Count = 2964480
Thread 2, Count = 2960384
Main, Count = 2965504
Thread 1, Count = 1777664
Thread 2, Count = 2961408
Main, Count = 2966528
Thread 2, Count = 2962432
Thread 1, Count = 1778688
Main, Count = 2967552
Thread 2, Count = 2963456
Main, Count = 2968576
Thread 1, Count = 1779712
Thread 2, Count = 2964480
Main, Count = 2969600
Thread 2, Count = 2965504
Main, Count = 2970624
Thread 1, Count = 1780736
Thread 2, Count = 2966528
Main, Count = 2971648
Thread 2, Count = 2967552
Main, Count = 2972672
Thread 1, Count = 1781760
Thread 2, Count = 2968576
Main, Count = 2973696
Thread 2, Count = 2969600
Main, Count = 2974720
Thread 1, Count = 1782784
Thread 2, Count = 2970624
Main, Count = 2975744
Thread 2, Count = 2971648
Main, Count = 2976768
Thread 1, Count = 1783808
Thread 2, Count = 2972672
Main, Count = 2977792
Thread 2, Count = 2973696
Main, Count = 2978816
Thread 1, Count = 1784832
Thread 2, Count = 2974720
Main, Count = 2979840
Thread 1, Count = 1785856
Thread 2, Count = 2975744
Main, Count = 2980864
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.

Last edited by jtshaw; 02-16-2005 at 10:51 PM.
 
Old 02-17-2005, 12:16 AM   #23
keiwu
Member
 
Registered: Feb 2005
Posts: 77

Original Poster
Rep: Reputation: 15
Quote:
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

Example output:
Code:
Main, Count = 2963456
Thread 1, Count = 1776640
Thread 2, Count = 2959360
Main, Count = 2964480
Thread 2, Count = 2960384
Main, Count = 2965504
Thread 1, Count = 1777664
Thread 2, Count = 2961408
Main, Count = 2966528
Thread 2, Count = 2962432
Thread 1, Count = 1778688
Main, Count = 2967552
Thread 2, Count = 2963456
Main, Count = 2968576
Thread 1, Count = 1779712
Thread 2, Count = 2964480
Main, Count = 2969600
Thread 2, Count = 2965504
Main, Count = 2970624
Thread 1, Count = 1780736
Thread 2, Count = 2966528
Main, Count = 2971648
Thread 2, Count = 2967552
Main, Count = 2972672
Thread 1, Count = 1781760
Thread 2, Count = 2968576
Main, Count = 2973696
Thread 2, Count = 2969600
Main, Count = 2974720
Thread 1, Count = 1782784
Thread 2, Count = 2970624
Main, Count = 2975744
Thread 2, Count = 2971648
Main, Count = 2976768
Thread 1, Count = 1783808
Thread 2, Count = 2972672
Main, Count = 2977792
Thread 2, Count = 2973696
Main, Count = 2978816
Thread 1, Count = 1784832
Thread 2, Count = 2974720
Main, Count = 2979840
Thread 1, Count = 1785856
Thread 2, Count = 2975744
Main, Count = 2980864
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.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
cut , paste or grep ziox Programming 1 12-15-2004 10:51 PM
xmessage cut and paste mlenehan Linux - General 3 06-17-2003 03:27 PM
cut and paste. argh! JustinHoMi Linux - General 7 11-12-2001 09:01 PM
cut and paste c0c0deuz Linux - Newbie 6 11-01-2001 12:38 PM
cut, copy and paste loganwva Linux - General 1 10-11-2001 01:37 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:12 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration