Thread: Pthreads problem

  1. #1
    Registered User
    Join Date
    Apr 2007
    Posts
    6

    Pthreads problem

    Hello everybody,

    I'm stuck with pthreads. I want to create a program which will run a persistent number of threads, by that i mean, if the number of threads i want to create is 5, the program should create 5 and if any of them finish, program should create more, so the number of threads which are working should be 5. I hope you understand what i mean, with my poor english
    So, my problem is, when i'm trying to pass a var to a thread (that goes like this, 1 line in a file goes to a 1 thread and so on), i'm getting wrong results. That's an example file which is opened and parsed line by line:
    Code:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    That's program code:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <pthread.h>
    
    
    
    /* THREADS */
    void *thread_function();
    int running_threads = 0;
    
    
    pthread_mutex_t pthr_running = PTHREAD_MUTEX_INITIALIZER;
    pthread_mutex_t accounts = PTHREAD_MUTEX_INITIALIZER;
    /***Global vars***/
    
    
    
    main(int argc , char *argv[])
    {
         	/* FILE */
    	FILE *file;
    	file = fopen("h.txt" , "r");
    	
    	int NTHREADS = atoi(argv[1]);
    	pthread_t thread_id[NTHREADS];
    	
    	int TERM = 0;
    	int i;
    	int linecounter = 0;
    	
    	while (! TERM) {
    		/* Get number of threads to create */
    		int pthr_for_create = NTHREADS - running_threads;
    		/* check if we need any */
    		if (pthr_for_create != 0 && pthr_for_create <= NTHREADS) {
    			/* Start creating them */
    			for(i = 0; i < pthr_for_create; i++)
       			{ 
          				char line[100];
    			        int loop_num = 0;	
    				while(fgets(line , 100 , file) != NULL) {
    					if (linecounter == loop_num) {
    						linecounter++;
    						break;
    					}
    					else {
    						loop_num++;
    					}
    				}
    				linecounter++;
    				
    				
    				/* Create */
    				pthread_create( &thread_id[i], NULL, thread_function, (void *)line);
    				
    				
    			}
    		}
    		/* Let finish any thread */
    		sleep (1);
    	}
    	fclose(file);
    	exit(0);
    }
    
    void *thread_function(void *account)
    {
    	pthread_mutex_lock( &pthr_running );
       		running_threads++;
       	pthread_mutex_unlock( &pthr_running );
    	
    	
    	
    		printf("\tWorking -> %d , Account-> %s" , pthread_self , account);
    	
    	
    	sleep(1);
    
    
    		printf("\t\t%d <- Finished\n" , pthread_self);
    
    	pthread_mutex_lock( &pthr_running );
       		running_threads--;
       	pthread_mutex_unlock( &pthr_running );
    
    
    	void *to_exit;
    	pthread_exit(to_exit);
    }
    And that's what i've got:

    Code:
            Working -> 4199040 , Account-> 9
            Working -> 4199040 , Account-> 9
            Working -> 4199040 , Account-> 16
            Working -> 4199040 , Account-> 20
            Working -> 4199040 , Account-> 20
                    4199040 <- Finished
                    4199040 <- Finished
                    4199040 <- Finished
                    4199040 <- Finished
                    4199040 <- Finished
            Working -> 4199040 , Account-> 20
            Working -> 4199040 , Account-> 20
            Working -> 4199040 , Account-> 20
                    4199040 <- Finished
                    4199040 <- Finished
                    4199040 <- Finished
            Working -> 4199040 , Account-> 20
            Working -> 4199040 , Account-> 20
            Working -> 4199040 , Account-> 20
            Working -> 4199040 , Account-> 20
            Working -> 4199040 , Account-> 20
                    4199040 <- Finished
                    4199040 <- Finished
    I understand that i didn't make a check function, to check if it's a last line to pass to a thread, and we should stop, so that's why i have so many "Account-> 20", but i don't understand why it's going like "9 9 16 20 20" , sometimes it's "9 9 9 16 20", and i want it to be like "1 2 3 4 5"

    Thanks for help

  2. #2
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    What about reading some books about thread synchronization?
    You start thread 1 and pass the pointer to the line var
    Then main thread resumes and saves new value to the line var
    Then 2nd thread is started
    then new value is passed to the line var
    Then second thread prints the value
    Then 1st thread prints the value (same value)
    Then main thread updates value
    etc
    So your program obviosly does what you tell it to do, but not what you want it to do.

    threads work independently.
    If you start one before another it does not guarantee that they will work in this order. There is no guarantee that thread will imediatly read info your pass, etc. You should take all of this into consideration.
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  3. #3
    Registered User
    Join Date
    Apr 2007
    Posts
    6
    I understand that, but, new "line" var is initiated every time when it comes to a "for" loop, or it's not? I thought when i'm going through the "for" loop, var "line" is initiated every time, and there is a memory space allocated for every "line" var or it's the same "line" var which is used every time?
    I'm a perl programmer

  4. #4
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    your local var is destroyed avery time you get to the end of for loop - if your thread does not read the memory before it - you can get the GPF just due to the access to the not used memory...

    In your case the each new instance of the line is allocated on the same address as the previous one - so instead of GPf you lucky get the new (already overwritten value)

    To allocate memory for every thread - use malloc on each iteration - and free memory inside the thread function after you finish processing data.
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  5. #5
    Registered User
    Join Date
    Apr 2007
    Posts
    6
    Ok, i get it, thank you very much

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Memory problem with Borland C 3.1
    By AZ1699 in forum C Programming
    Replies: 16
    Last Post: 11-16-2007, 11:22 AM
  2. Someone having same problem with Code Block?
    By ofayto in forum C++ Programming
    Replies: 1
    Last Post: 07-12-2007, 08:38 AM
  3. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  4. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM
  5. beginner problem
    By The_Nymph in forum C Programming
    Replies: 4
    Last Post: 03-05-2002, 05:46 PM