I am implementing a threads library in C and I am stuck on the meaning of pthread_yield(). I have looked it up on the man page in the terminal but I did not really understand the explanation. Could someone explain it to me?
Note well that its name notwithstanding, pthread_yield is not standardized. Its Linux manual page says this, for example:
This call is nonstandard, but present on several other systems. Use the standardized sched_yield(2) instead.
The specifications for sched_yield() are written in much the same terms as those of pthread_yield(), however:
The sched_yield() function shall force the running thread to relinquish the processor until it again becomes the head of its thread list. It takes no arguments.
This just means that the thread that calls the function allows other threads and processes a chance to run, waiting to resume until its turn comes again. It is not necessary to do this in a preemptive multitasking system such as pthreads is designed around -- the kernel manages assigning CPU time to threads and processes without any such help -- but there may occasionally be special cases where it smooths out thread scheduling issues.
In the GLIBC, pthread_yield merely invokes sched_yield() system call (cf. nptl/pthread_yield.c in the source tree of the library):
/* With the 1-on-1 model we implement this function is equivalent to
the 'sched_yield' function. */
int
pthread_yield (void)
{
return sched_yield ();
}
As you are implementing a thread library, note that the above GLIBC source code (2.31 version) of pthread_yield() results in an unusual pthread API behavior which may be an implementation bug as it returns directly the result of sched_yield(). Like most of the Linux system calls, the latter returns -1 and sets errno if it fails (even if the manual specifies that it actually never returns in error). So, theoretically, this makes pthread_yield() return -1 and set errno in case of error although the pthread API usually returns 0 if successful and the error number in case of error (errno is not supposed to be set). So, the manual is wrong or at least does not comply with the GLIBC's implementation when it describes the returned value as:
RETURN VALUE
On success, pthread_yield() returns 0; on error, it returns an error number.
The expected source code could be something like:
int
pthread_yield (void)
{
return sched_yield() == -1 ? errno : 0;
}
For example, pthread_sigmask() is coded as:
int
pthread_sigmask (int how, const sigset_t *newmask, sigset_t *oldmask)
{
[...]
return sigprocmask (how, newmask, oldmask) == -1 ? errno : 0;
[...]
}
which complies with what is stated in the manual:
RETURN VALUE
On success, pthread_sigmask() returns 0; on error, it returns an
error number.
Related
I am working on a project in which a "student" thread will use a semaphore to wake up a "TA" thread.
I have a semaphore called studentNeedsHelp_Sem
I initialize it with sem_init(&studentNeedsHelp_Sem, 0 ,0);
Before any of my student or TA threads are even created, I include these 3 lines:
printf("DEBUG WAITING\n");
sem_wait(&studentNeedsHelp_Sem);
printf("DEBUG DONE WAITING\n");
What should happen: DEBUG WAITING is printed, then we have to wait until a student actually needs help (and calls sem_post(&studentNeedsHelp_Sem) ) to see DEBUG DONE WAITING
What is happening: both are printed before my student threads even start.
(I am working in C on OSX, using POSIX pthreads)
Thank you for your help!
Check the return value of sem_wait (as you should always do whenever calling a library function or system call). It's probably negative, indicating an error; look at errno or use perror to display the error. I wouldn't be surprised if it's EDEADLK.
Indeed, if no threads have been started, then surely there is nobody to post the semaphore. So sem_wait would never return at all. This is a deadlock; your program is waiting for something that provably can never happen. It may be that OSX's thread library detects this and has sem_wait return with an error, on the assumption that this isn't what you intended, and at least if sem_wait returns your program has a chance to recover.
For anyone stumbling across this question, as it turns out, MacOS does not support unnamed POSIX semaphores. A good alternative is named POSIX threads. They don't appear to differ much in their function besides initialization and destruction.
Instead of using sem_init, you can declare them with
sem_t *semaphore = sem_open("/semaphoreName", O_CREAT, 0644, 1);
You can read more about those parameters here.
You will use sem_wait and sem_post just as you would unnamed semaphores.
Instead of sem_destroy, you will use
sem_close(semaphore);
and then subsequently
sem_unlink("/semaphoreName");
This is all includes in the <semaphore.h> library just as unnamed semaphores are.
Hope this helps someone that is just as confused as I was.
#include<stdio.h>
#include<stdlib.h>
main()
{
printf("Hello World..\n");
system("ls");
}
Here...ON SUCCESSFUL execution system function returns the statys of "ls" command..and ON FAILURE it returns -1..
so can anyone help me to get this FAILURE condition for system function that gives return value as "-1"
The system function returns -1 if system itself fails, not if the command it invokes fails. For example, system returns -1 if the fork call fails. This can happen if your system is very short on resources, such as memory, or if your system imposes a limit on the number of processes you can run.
If the command fails (for example if you call system("false")), the value returned by system isn't simply the return value of the command; it's the value returned by the wait system call; man 2 wait for more information. (This assumes a Unix-like system; the behavior of system() on other operating systems differs.)
Of course if you want to see the value returned by a call to system, you'll need to store that value in a variable:
int result = system("ls");
You should read the documentation for the system function.
If you're trying to cause system to fail and return -1, one way to do it is to use it to invoke your program recursively. This can consume a lot of memory, and may interfere with your system. Do this only if you're the only person using the system, and you don't mind possibly interfering with its operation.
(Incidentally, the definition for main should be int main(void), not just main(), though that's not directly relevant. Prior 1999, omitting the return type would default to int; that's no longer permitted, but many compiler still support the old form. Empty parentheses do not specify the number of parameters; (void) explicitly says that there are no parameters, and is the preferred form.)
I'm creating a presentation on how to program in C, and since I'm fairly new to C, I want to check whether my assumptions are correct, and what am I missing.
Every C program has to have an entry point for the OS to know where to begin execution. This is defined by the main() function. This function always has a return value, whether it be user defined or an implicit return 0;.
Since this function is returning something, we must define the type of the thing it returns.
This is where my understand starts to get hazy...
Why does the entry point needs to have a return value?
Why does it have to be an int?
What does the OS do with the address of int main() after the program executes?
What happens in that address when say a segfault or some other error halts the program without reaching a return statement?
Every program terminates with an exit code. This exit code is determined by the return of main().
Programs typically return 0 for success or 1 for failure, but you can choose to use exit codes for other purposes.
1 and 2 are because the language says so.
For 3: Most operating systems have some sort of process management, and a process exits by invoking a suitable operating system service to do so, which takes a status value as an argument. For example, both DOS and Linux have "exit" system calls which accept one numeric argument.
For 4: Following from the above, operating systems typically also allow processes to die in response to receiving a signal which is not ignored or handled. In a decent OS you should be able to distinguish whether a process has exited normally (and retrieve its exit status) or been killed because of a signal (and retrieve the signal number). For instance, in Linux the wait system call provides this service.
Exit statuses and signals provide a simple mechanism for processes to communicate with one another in a generic way without the need for a custom communications infrastructure. It would be significantly more tedious and cumbersome to use an OS which didn't have such facilities or something equivalent.
I write a program using pthread.
Environment:windows 7 , CYGWIN_NT-6.1 i686 Cygwin , gcc (GCC) 4.5.3
The source code
#include<stdio.h>
#include<pthread.h>
void *th_func(void *p)
{
int iLoop = 0;
for(iLoop = 0;iLoop<100;iLoop++)
{
printf("Thread Thread Thread Thread\n");
}
return;
}
int main()
{
int iLoop = 0;
pthread_t QueThread;
printf("Main : Start Main\n");
printf("Main : Start Create Thread\n");
pthread_create(&QueThread,NULL,th_func,NULL);
printf("Main : End Create Thread\n");
for(iLoop = 0;iLoop<100;iLoop++)
{
printf("Main Main Main Main\n");
}
pthread_join(QueThread,NULL);
printf("Main : End Main\n");
printf("---------------\n");
return 0;
}
When I compile the source code, there are no warnings or errors,but it's output is weird.
A part of it's output
Main : Start Main
Main : Start Create Thread
Thread Thread Thread ThreThread Thread Thread Thread
Main Main Main Main
Thread Thread Thread Thread
Main Main Main Main
I want to know the cause of such phenomenon.
In this output, Main : End Create Thread is not printed completely. And at line 3, a newline \n at the end of "Thread Thread Thread Thread\n" disappear.
Is everyone's output like this? It does not occur every time, but occurs sometime.
If I use mutex to call printf safely,the weird output seem to be stopped.
POSIX says printf is thread-safe, and according to Cygwin.com, cygwin provides posix-style API. However, there is the unexpected output.
Is printf really thread-safe?
I executed the same program 100 times in Linux(Ubuntu), and this output did not occur.
In addition, I have not understood the reason why some words on the output disappeared.
This looks like it may be a bug in Cygwin, or maybe something is misconfigured. Several answer here indicate that 'thread safe' only promises that the function won't cause harm to the program, and that thread safety doesn't necessarily mean that a function is 'atomic'. But, as far as I know, POSIX doesn't formally define 'thread safe' (if anyone has a pointer to such a definition, please post it in a comment).
However, not only does POSIX specify that printf() is thread safe, POSIX also specifies that:
All functions that reference ( FILE *) objects shall behave as if they use flockfile() and funlockfile() internally to obtain ownership of these ( FILE *) objects.
Since printf() implicitly references the stdout FILE* object, all printf() calls should be atomic with respect to each other (and any other function that uses stdout).
Note that this might not be true on other systems, but in my experience it does hold true for many multi threaded systems.
The POSIX standard has functions like putc_unlocked() where the commentary says:
Versions of the functions getc(), getchar(), putc(), and putchar() respectively named getc_unlocked(), getchar_unlocked(), putc_unlocked(), and putchar_unlocked() shall be provided which are functionally equivalent to the original versions, with the exception that they are not required to be implemented in a thread-safe manner. They may only safely be used within a scope protected by flockfile() (or ftrylockfile()) and funlockfile(). These functions may safely be used in a multi-threaded program if and only if they are called while the invoking thread owns the (FILE *) object, as is the case after a successful call to the flockfile() or ftrylockfile() functions.
That clearly indicates that the low-level functions for single character I/O are normally thread-safe. However, it also indicates that the level of granularity is a single character output operation. The specification for printf() says:
Characters generated by fprintf() and printf() are printed as if fputc() had been called.
And for putc(), it says:
The putc() function shall be equivalent to fputc(), except that if it is implemented as a macro it may evaluate stream more than once, so the argument should never be an expression with side-effects.
The page for fputc() doesn't say anything about thread-safety, so you have to look elsewhere for that information.
Another section describes threads and says:
All functions defined by this volume of POSIX.1-2008 shall be thread-safe, except that the following functions need not be thread-safe.
And the list following includes the *_unlocked() functions.
So, printf() and fputc() have to be thread-safe, but the writing by printf() is done 'as if' by fputc(), so the interleaving of output between threads may be at the character level, which is more or less consistent with what you see. If you want to make calls to printf() non-interleaved, you would need to use the flockfile() and funlockfile() calls to give your thread ownership of stdout while the printf() is executed. Similarly for fprintf(). You could write an fprintf_locked() function quite easily to achieve this result:
int fprintf_locked(FILE *fp, const char *format, ...)
{
flockfile(fp);
va_list args;
va_start(args, format);
int rc = vfprintf(fp, format, args);
va_end(args);
funlockfile(fp);
return rc;
}
You could insert a fflush(fp) in there if you wished. You could also have a vfprintf_locked() and have the function above call that to do the lock, format, (flush) and unlock operations. It's probably how I'd code it, trusting the compiler to inline the code if that was appropriate and doable. Supporting the versions using stdout is likewise pretty straight-forward.
Note the fragment of POSIX specification for flockfile() quoted by Michael Burr in his answer:
All functions that reference (FILE *) objects, except those with names ending in _unlocked, shall behave as if they use flockfile() and funlockfile() internally to obtain ownership of these (FILE *) objects.
Apart from the odd parentheses around the FILE *, these lines impact all the other standard I/O functions, but you have to know that these lines exist in one of the less frequently used man pages. Thus, my fprintf_locked() function should be unnecessary. If you find an aberrant implementation of fprintf() that does not lock the file, then the fprintf_locked() function could be used instead, but it should only be done under protest — the library should be doing that for you anyway.
Just because a function is thread-safe, it doesn't mean it's atomic.
In your case, if you want to ensure that your output don't get interleaved, you need to use a mutex to ensure that only one thread calls printf at a time.
Threads behave like this for a reason. If threads were executed one after another and not 'at the same time' (in an interleaved manner), there would be no point in this kind of 'concurrency'. When you use mutexes, the threads will be blocked according to your intention, and they generate the expected output.
Also, you write return; in a function that returns void * and that is undefined behavior, so anything can happen when running your program.
I will put this in a simple way you have two threads which are trying to access a resource. And also there is no kinds priority checks or anything like a mutex. Theoretically, threads without mutex or priority gets assigned with resources randomly. try creating two threads with one thread printing yes and the other one printing no. you will find this unusual behavior. Also remember running time is different for different threads in this case. If you try the same stuff with one thread writing the info to a file and other guy writing to console. You will not encounter such an issue. Hope that helps....
I have sort of a homework and it asks me to end the program gracefully without explicit termination such as calling exit() or killing the threads.
However I cannot think of any other methods than return 0, so what are the methods to end a program gracefully?
Killing the threads is absolutely not a graceful way to terminate a program. I think what your instructor means is that all your parent threads should wait on their child threads before terminating themselves.
Ideally, an explicit call pthread_exit from the main thread would ensure that all it's children continue running even after it exits. Refer to this link. But, the safest way to wait on your child threads before exiting is to use pthread_join.
Nevertheless, exit(0) is the graceful return for a process as such.
I think you are missing to tell us that you have a multi-threaded program. I suppose that the the idea of gracefully terminating the program is meant to terminate all your threads by setting a flag or something like that. And then only to terminate your main after all your threads have provably ended. The way you actually then terminate your main is of lesser importance.
exit(0) generally indicates that process (your program) terminated gracefully. In case of error it would exit(-1) or some other error code.
See my comment.
main will by default return 0 in the lack of a return 0; statement.
See §5.1.2.2.3¶1 of the C99 standard.
If the return type of the main function is a type compatible with int, a return from the
initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument; reaching the } that terminates the
main function returns a value of 0. If the return type is not compatible with int, the
termination status returned to the host environment is unspecified.
So, the following terminates gracefully although implicitly, distinguished from an explicit exit or return in main.
main() { }
They may be referring to how you handle errors in lower-level routines. Rather than doing something like
printf("ERROR: couldn't initialize the claveman\n");
exit(1);
You would return from that routine (possibly printing the error message at that level or waiting to do it at a higher level like main()).
return CLAVEMAN_INITIALIZE_ERROR;
All your routines would return zero for success or non-zero error codes, up until the code in main was able to return either EXIT_SUCCESS or an error code indicating the failure.
No idea what they could mean with gracefully but my first idea was just a return 0.
Or exit(0)