Thread: Running 2 functions simultaneously

  1. #1
    Registered User
    Join Date
    Apr 2009
    Posts
    5

    Running 2 functions simultaneously

    I'm making a program that requires 2 functions to be run at once. One function checks for user input and writes the input to a file, the other function reads that file and checks to see if it has changed. I cant have one run before the other, they NEED to be run at the same time. All my code is written, except for the part that runs the functions, this is basically what i want in the end:

    Code:
    int write(void)
    {
         code for this function
         start();
    }
    
    int read(void)
    {
         code for this function
         main();
    }
    
    int start(void);
    {
         write(); read(); /*WANT TO RUN THESE AT SAME TIME*/
    }
    
    int main()
    {
         code for this function
         start();
    }
    This is the format i NEED to have, so any recommendations that involve changing the format of my code TOO much will only be counter-productive in this situation. Thanks guys =)

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    NEVER call main() from any other fucntion in your code. In C++ it is illegal to do that, in C it is indeed legal, but it's NEVER a good thing to do [1].

    To make two functions execute simultaneously, you need to use multiple threads.

    To make two functions APPEAR to execute simultaneously, use non-blocking operations, or operations using short timeouts.

    Judging from your apparent small experience with programming, I would suggest that you probably need to practice the basics in C first.


    [1] Of course if you are working on the C runtime code that prepares the environment before calling main, it is valid to call main from there - that's after all what that bit of code does. But that should be the ONLY code that calls main. And most people do not even know this code exists, never mind write their own version. I have done it about two-three times.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    Apr 2009
    Posts
    5
    Soo... yeah I'm only 15 I've been programming for a year, so yeah my knowledge isnt huge in the language =P but I appreciate the reply. So I'm really not sure how to go about this multi thread stuff. I know the basics of the language, my code was a simple outline, if you want I can post the real code and maybe it will make some more sense. I didnt want to do this because i know there are better ways to make a program like this, and I know somebody is going to be like "why are you doing it like that just do this:" but this is the way the program is meant to work and I dont feel like explaing why I'm using such an odd method to accomplish this. But anyway, this is the code:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    char name[10]; /*Display Name*/
    int x=1; /*Loop*/
    
    char chat[10000]; /*Contents of chat.lsm*/
    FILE *textread; /*For fgets and fopen*/
    FILE *ntr; /*New textread which goes into nch*/
    char nch[10000]; /*New chat which is compared with old chat*/
         
    
    int send(void)
    {
         char text[10000]; /*User inputed message*/
         char newtext[10000]; /*Message with display name*/
         FILE *textwrite; /*For fwrite*/
         size_t count; /*For fwrite and fopen*/
         
         gets(text);
         sprintf(newtext,"%s: %s",name,text);
         
         textwrite = fopen("chat.lsm", "wb");
         printf("\n\n");       
         count = fwrite(newtext, 1, strlen(newtext), textwrite);
         printf("", (unsigned long)count, fclose(textwrite) == 0 ? "succeeded" : "failed");  
         
         room();   
    }     
    
    int receive(void)
    {    
         textread = fopen ("chat.lsm", "rt");
         if(textread==NULL)
         {
              main();
         } 
    
         fgets(chat, 1000000, textread);
        
         printf("%s\n\n",chat);
       
         fclose(textread);
         sleep(100);
         
         main();
    } 
    
    int room(void)
    {
        receive(); send();
    }                  
    
    int main()
    {   
        while(x==1) 
        {
             x=x+1;
             system("color 1f");
        
             printf("LSM Chat 2.0\n\n");
             system("PAUSE");
        
             system("CLS");
             printf("Enter desired display name. (10 character maximum)\n\nDisplay Name:  ");
             gets(name);
             fflush(stdin);
             printf("\nYour display name is %s.\n\n",name);
             system("PAUSE");
             
             system("CLS");
             room(); 
        }
             
        ntr = fopen ("chat.lsm", "rt");
        if(ntr==NULL)
        {
             sleep(100);        
             main();
        } 
        
        
        fgets(nch, 1000000, ntr);     
        if (strcmp (nch,chat) != 0)
        {
             receive();
        }  
        fclose(ntr);
        memset (nch,'`',10);
        sleep(100);
        main();
    }
    once again, thanks for the fast reply =) i hope this helps

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Have you heard of "while" and "for":
    Code:
        ntr = fopen ("chat.lsm", "rt");
        if(ntr==NULL)
        {
             sleep(100);        
             main();
        }
    This is exactly the "do not call main" that I was talking of earlier. Also, perhaps printing a message to say "file could not be opened" may help the debugging of problems with the file not being present or some such.

    Code:
        printf("", (unsigned long)count, fclose(textwrite) == 0 ? "succeeded" : "failed");
    Huh? What on earth is this meant to do?

    Don't use gets - it does not check if the input actually fits, so if someone falls asleep pressing the A key, then your program will crash - use fgets() with stdin as the file.
    Code:
         gets(text);
    It is perhaps worse for "name", which can actually quite possibly be longer than 9 characters. My full name (not counting middle-name) is a few characters more than that. Trusing users to READ, UNDERSTAND, AND OBEY instructions such as "10 characters max" is not a good idea in general.

    Code:
         char text[10000]; /*User inputed message*/
         char newtext[10000]; /*Message with display name*/
    ...
         sprintf(newtext,"%s: %s",name,text);
    Let's assume that text is actually 9999 characters of content. What will happen to newtext?

    Code:
    char chat[10000]; /*Contents of chat.lsm*/
    ...
         fgets(chat, 1000000, textread);
    Do NOT lie to fgets() as to how big your buffer is.

    Code:
    int x=1; /*Loop*/
    ...
        while(x==1) 
        {
             x=x+1;
    ...
    If x is a flag to see if you want to loop again or not, why not use x = 0 or x = 2 to make it "not 1". Also, is there any particular reason it is declared as a global variable?

    As to how you solve the problem, I think all of my original answer still applies. Either use threads or use non-blocking functions, but learn how to program first. Note, it took me quite some time to learn to program too - but I've been programming since early 1980's now.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    I agree with matsp that you should get more practice with basic C first, but if you REALLY want to do multithreading now, you need to find a threading library first, since there is no standard way to do threading in C.

    Threading libraries are platform-dependent (there are a few cross-platform ones in C++, including C++0x threads, but I'm not aware of any for C). On Windows the most popular library is probably Win32 API. Everywhere else it's POSIX threads (pthreads). You can find plenty of tutorials online.

    They are NOT easy, though. When concurrency is involved you get nasty things like deadlocks, race conditions, data corruptions, if you don't plan things out properly, or don't protect your data properly.

    I really think it's quite a bit beyond your experience at this point.

  6. #6
    Registered User
    Join Date
    Jan 2009
    Posts
    103
    I agree with the people above me, do some more before doing threads. If you don't use threads very well, they quickly get out of hand and make your program a nightmare to run.

    Ya might want to look into Java for this if you know the basics of it cause its cross platform and its really easy to use (in the threads matter at the least). Don't worry about your age, i'm only 11 :P

  7. #7
    Registered User
    Join Date
    Apr 2009
    Posts
    5
    Quote Originally Posted by matsp View Post
    Have you heard of "while" and "for":
    Code:
        ntr = fopen ("chat.lsm", "rt");
        if(ntr==NULL)
        {
             sleep(100);        
             main();
        }
    This is exactly the "do not call main" that I was talking of earlier. Also, perhaps printing a message to say "file could not be opened" may help the debugging of problems with the file not being present or some such.

    Code:
        printf("", (unsigned long)count, fclose(textwrite) == 0 ? "succeeded" : "failed");
    Huh? What on earth is this meant to do?

    Don't use gets - it does not check if the input actually fits, so if someone falls asleep pressing the A key, then your program will crash - use fgets() with stdin as the file.
    Code:
         gets(text);
    It is perhaps worse for "name", which can actually quite possibly be longer than 9 characters. My full name (not counting middle-name) is a few characters more than that. Trusing users to READ, UNDERSTAND, AND OBEY instructions such as "10 characters max" is not a good idea in general.

    Code:
         char text[10000]; /*User inputed message*/
         char newtext[10000]; /*Message with display name*/
    ...
         sprintf(newtext,"%s: %s",name,text);
    Let's assume that text is actually 9999 characters of content. What will happen to newtext?

    Code:
    char chat[10000]; /*Contents of chat.lsm*/
    ...
         fgets(chat, 1000000, textread);
    Do NOT lie to fgets() as to how big your buffer is.

    Code:
    int x=1; /*Loop*/
    ...
        while(x==1) 
        {
             x=x+1;
    ...
    If x is a flag to see if you want to loop again or not, why not use x = 0 or x = 2 to make it "not 1". Also, is there any particular reason it is declared as a global variable?

    As to how you solve the problem, I think all of my original answer still applies. Either use threads or use non-blocking functions, but learn how to program first. Note, it took me quite some time to learn to program too - but I've been programming since early 1980's now.

    --
    Mats
    haha ok here i go:
    i know how to use for and while, but i had to jump back to main because its the only way for the life of me i could make the program check for a change in the chat file correctly. if you could tell me the correct way that would be great.

    as for that wierd line, i pasted that in from a previous program i made not realizing that i didnt need it, so yeah, takin that out =P

    ok so i changed gets(name); to fgets(name,10,stdin); but it didnt change anything, i could still easily enter more than 10 characters. im not sure if this simply prefented the crash if the buffer is filled beyond capcity or if this was acually supposed to cut off any byted beyond the allowed buffer...

    about lieing to fgets, that was my bad =P just a typo but thanks for pointing it out =)

    good point about just using x=2 or x=1. ill change that. i declared it as a global variable because i wasnt sure if i would have to use it in another function, soi just played it safe. once i finish a program i clean up the code dont worry =P

  8. #8
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by blkhockeypro19 View Post
    i know how to use for and while, but i had to jump back to main because its the only way for the life of me i could make the program check for a change in the chat file correctly. if you could tell me the correct way that would be great.
    THat comes from lack of experience, particularly with refactoring code.
    Here is one way of removing all of the calls to main:
    Code:
    int main()
    {
        do
        {
    
            // ...
    
            if (ntr==NULL)
            {
                 sleep(100);        
                 continue;
            }
    
            fgets(nch, 1000000, ntr);     
            if (strcmp(nch,chat) != 0)
            {
                 receive();
                 continue;
            }  
    
             // ...
    
        }
        while (1);
    }
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Is it legal to have functions within functions?
    By Programmer_P in forum C++ Programming
    Replies: 13
    Last Post: 05-25-2009, 11:21 PM
  2. An array of macro functions?
    By someprogr in forum C Programming
    Replies: 6
    Last Post: 01-28-2009, 07:05 PM
  3. Running Normal Functions inside of a class
    By Padawan in forum C++ Programming
    Replies: 2
    Last Post: 04-09-2004, 11:52 PM
  4. Expression Manipulator v0.2 (bug fixes, functions)
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 05-26-2003, 04:52 PM
  5. trouble defining member functions
    By dP munky in forum C++ Programming
    Replies: 7
    Last Post: 04-13-2003, 08:52 PM