LinuxQuestions.org
Register a domain and help support LQ
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 11-01-2013, 04:54 PM   #1
pratham29
LQ Newbie
 
Registered: Oct 2013
Posts: 8

Rep: Reputation: Disabled
Threading program with various counters


Study the example program in the attached file. This program creates a new thread. Both the main thread and the new thread then increment the variable counter 20 times. But the program itself produces some unexpected results.

1. Compile and run the program on a Linux system. Find out what results it produces and explain the results.
Compile as follows:
$ gcc thread2.c -o thread2 -lpthread

Run using the following command
$ ./thread2

2. Modify the program so that the variable counter has a value of 40 when the program ends.
Hint: use synchronization primitives.

Please submit a zip file labelled as Assignment4_Yourname.zip. It should include a PDF file with explanation of the results and a C source file with the modified program.


Clarification: One some systems, you might not see the unexpected result right away. In that case, run the program several times and see if you get any unexpected results. If you still don't see anything, insert some sleep statements into both the thread functions and manually study the code and point out what's wrong with the code.

____________________________________________________________________________________________________ ______________________

Code:
/* Save this program as thread2.c */
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
int counter=0;
 void *thread_function(void *arg) {
  int i,j;
  for ( i=0; i<20; i++ ) {
    j=counter;
    j=j+1;
    printf(".");
    fflush(stdout);

    counter=j;
}
  return NULL;
}
int main(void) {
  pthread_t mythread;
  int i;
  if ( pthread_create( &mythread, NULL, thread_function, NULL) ) {
    printf("error creating thread.");
    abort();
}
  for ( i=0; i<20; i++) {
    counter=counter+1;
    printf("o");
    fflush(stdout);
 
}
  if ( pthread_join ( mythread, NULL ) ) {
    printf("error joining thread.");
    abort();
  }
  printf("\ncounter equals %d\n",counter);
  exit(0);
}
OUTPUT:
guest@ubuntu:~$ cd Desktop/
guest@ubuntu:~/Desktop$ gcc thread2.c -o thread2 -lpthread
guest@ubuntu:~/Desktop$ ./thread2
oooooooooooooooooooo....................
counter equals 40
guest@ubuntu:~/Desktop$


I get the following output, kindly help me with the question 2 part.

Thanks in advance.
Regards,
Pratham
 
Old 11-01-2013, 04:57 PM   #2
Habitual
LQ Addict
 
Registered: Jan 2011
Location: Youngstown, Ohio
Distribution: LM17.1/Xfce4.11.8
Posts: 7,163
Blog Entries: 10

Rep: Reputation: 1979Reputation: 1979Reputation: 1979Reputation: 1979Reputation: 1979Reputation: 1979Reputation: 1979Reputation: 1979Reputation: 1979Reputation: 1979Reputation: 1979
Do not post homework assignments verbatim. We're happy to assist if you have specific questions or have hit a stumbling point, however. Let us know what you've already tried and what references you have used (including class notes, books, and searches) and we'll do our best to help. Keep in mind that your instructor might also be an LQ member.

Teachers hang out here too.
 
Old 11-01-2013, 05:23 PM   #3
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,602

Rep: Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241
Oh, it is sufficiently specific.

counter is a global variable - and without synchronized access, each thread MAY retrive the value as the value gets updated... at random times. The actions on the variable counter MAY get updated before the main thread increments it.

Because it isn't synchronized, the end result depends on the system.

On my system, I get:
Code:
$./a.out
oooooooooooooooo.o...................ooo
counter equals 24
$./a.out
ooooo........ooooooooooooooo............
counter equals 21
$ !!
./a.out
ooooo.ooooooooooooooo...................
counter equals 21
$
But then, I have multiple processors.

What happens is that the second thread gets initiated... but due to scheduling delays the original thread continues running - producing a string "o"s... By the time the second thread gets started (it has to migrate to a second processor), several "ooo..." are output BEFORE the first "." from the second thread. In the meantime, there is also buffer packing going on (which delays things), and packs a number of bytes together. In fact, this may be the overriding effect putting so many "o"s together.

The reason the counter gets the "wrong" output is again due to the scheduling.
The second thread is going to set the value "20". The primary thread is just incrementing counter. The earlier the child gets to run, the higher the count will be.

If the main thread runs first, the value will be closest to "20". If the second thread runs first the value will be closer to 40. But note, "counter" is itself NOT INITIALIZED, and can be a source of additional problems.

And the reason the output string is as it is, has to do with the runtime buffers... you have no synchronization with them so whatever you get is up to how things get scheduled... and the timing of the buffer outputs...

It is a "good" example of how NOT to approach threading.
 
Old 11-02-2013, 04:54 PM   #4
pratham29
LQ Newbie
 
Registered: Oct 2013
Posts: 8

Original Poster
Rep: Reputation: Disabled
I am still getting the same output counter= 40 for every compilation , can you explain about the variable outputs you received
 
Old 11-03-2013, 03:17 AM   #5
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,602

Rep: Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241
I did. It is relatively random, depending on how process scheduling (and how quickly) is done. It also depends on general system load.

It sounds very much like you have a single CPU.
 
Old 11-03-2013, 08:05 AM   #6
coopster
LQ Newbie
 
Registered: Sep 2010
Location: Central Texas, USA
Distribution: fedora 17
Posts: 2

Rep: Reputation: 0
Hi.

So p~29 has this hwork problem but what's really happening here?
I guess the counter represents some real world process, and he basically has two threads that need to update their "outputs" based on accessing that first process? Or I suppose the first thread instance could be whatever process, and the second thread executes before or during the first? So is the point to get both threads to count to 40, or count to 40 simultaneously, or one not to complete the count until the other catches up (completes)?

jpollard, thanks. Q: Would you (he) then put a lock or some other control on his code before first count, or is that only if a person is trying to make them put out a '.' or an 0 syncronously?
 
Old 11-03-2013, 10:32 AM   #7
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,602

Rep: Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241Reputation: 1241
In neither case would work...

What you are seeing is the problem with multi-threading at the fine grain level of an instruction - 10 nanoseconds or so.

The counter doesn't represent squat. It is just demonstrating that synchronization is not reliable at that level. You can put locks on the counter variable... Won't fix much
but it would get more reliable.

The major problem is the coarse grained process scheduling done relative to the fine grained acts of counting. Which ever process starts first gets the most access to the counter... When it finishes the other gets access.

And the same problem applies to the use of the file pointer used for output.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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
[SOLVED] Port Counters jayadhanesh Linux - Software 5 08-13-2012 07:02 PM
hi , i have done a char server program using Linux with multi threading concept ipsitanayak Programming 1 06-18-2012 07:41 AM
Can't zero-out counters in iptables didooofidooo Linux - Security 5 02-25-2010 03:51 PM
python program,random crashes,threading jabfinger Programming 4 01-27-2010 02:15 PM
multi threading slower than single threading on dual core. why? nebojsa.andjelkovic Programming 13 01-30-2007 10:56 PM


All times are GMT -5. The time now is 04:47 PM.

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
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration