using of POSIX threads

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Jianwee
    New Member
    • Feb 2010
    • 7

    using of POSIX threads

    Hi all,

    I have some questions regarding the usage of POSIX threads. I would like to ask:

    1) Is it possible if in a thread, I were to run a scanf function in order to change the value of a global variable?

    2) Do I use scanf or std::cin? And why?

    eg.
    Code:
    void 
    *detectKey(void *arg)
    {
        int y;
        scanf("%d",&y);
        while (y != 1)
        {
    	if (!::stopRobo)
    	{
    		::orderStop = 1;
    		::stopRobo = 1;
    		std::cout << "ORDERED TO STOP!!!" << endl;
    		break;
    	}
        }
        pthread_exit(0);
    }
  • donbock
    Recognized Expert Top Contributor
    • Mar 2008
    • 2427

    #2
    You must be careful to use only reentrant functions within threads. Is scanf reentrant? I don't know.

    Comment

    • Banfa
      Recognized Expert Expert
      • Feb 2006
      • 9067

      #3
      scanf can not be re-entrant since it uses a system resource, stdin, and the C library has no knowledge of multi-threading so can not protect access to that resource.

      You can get round that of course by only using scanf from a single thread.

      printf has a similar problem.

      Comment

      • Jianwee
        New Member
        • Feb 2010
        • 7

        #4
        Then should I use std::cin instead?

        Comment

        • donbock
          Recognized Expert Top Contributor
          • Mar 2008
          • 2427

          #5
          It is the same issue -- stdin (or std::cin) is a single sytem resource. A single system resource cannot be casually shared by separate threads.

          Comment

          • Jianwee
            New Member
            • Feb 2010
            • 7

            #6
            Then is there any other way to detect keyboard inputs? For example, some C++ programs can be stopped with the Ctrl+C method. They are implementing some sort of thread to detect the keypress right?

            Comment

            • Banfa
              Recognized Expert Expert
              • Feb 2006
              • 9067

              #7
              No the OS is producing a trap in response to the CTRL-C and sending it to the program.

              What you can do (and what I often do for printf or std::cout) is use a pthread_mutex to prevent access to the function from more than 1 thread at a time. Typically a write a wrapper function that is the only function calling std::cout and use a pthread_mutex to ensure that that function is thread-safe then it does not matter that std::cout is not re-entrant because it is only being called from a single thread-safe function.


              Note that thread-safe and re-entrant have subtlely different meanings.

              re-entrant means that a function can actually be exectuted by multiple threads at the same time. A re-entrant function typically only uses parameters passed to it and variables with automatic storage-class and do not access system resources.

              thread-safe means that multiple threads can successfully call the function simultaneously and the function itself prevents the bits that should not be executed by more than one thread at a time from being executed by more than 1 thread, typically using a mutex to achieve this. The function can nota actually be executed (in its entirety) simulataneously by more than 1 thread, the function code takes measure to ensure that this requirement is met.

              Comment

              • Tassos Souris
                New Member
                • Aug 2008
                • 152

                #8
                Write a thread-safe wrapper for the input and output functions, say safe_printf() and safe_scanf().

                Code:
                #include <stdarg.h>
                #include <stdio.h>
                #include <pthread.h>
                
                // Mutex to protect the input and output streams
                static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
                
                // Perform a thread-safe printf() operation
                // Return the value from printf()
                int safe_printf( const char * restrict format, ... ){
                    int returnValue; // value returned from vprintf()
                    va_list ap; 
                
                    // Lock the stream (without error cheking)
                    pthread_mutex_lock( &mutex );
                
                    // Do the printf()
                    va_start( ap, format );
                    returnValue = vprintf( format, ap );
                    va_end( ap );
                
                    // Unlock the stream  now... (without error checking)
                    pthread_mutex_unlock( &mutex );
                
                    return ( returnValue );
                }
                You can easily extend the above scheme and for other FILE streams (use vfprintf()).

                Comment

                Working...