I am working on some C code and am having a problem with locking a mutex. The code does a call to a function and this function locks a mutex to ensure a file pointer doesn't get overwritten, this works fine for several instances, probably about 10-20 separate calls of the function being called, but on the next call, pthread_mutex_lock will return with a result of 22. I've then put this result into strerror(); and got back invalid argument.
What does invalid argument means, thanks for any help you can provide.
22 is ENVAL error code which means invlalid argument. Make sure that you have initilized you mutex, or if at some point you have unitilized it somewhere.
Also man pthread_mutex_lock says:
EINVAL
The mutex was created with the protocol attribute having the
value PTHREAD_PRIO_PROTECT and the calling thread's priority is higher
than the mutex's current priority ceiling.
I don't quite understand this but it probably means that you need to change thread's priority. I am not sure. Maybe someone else can shine light on it.
Sounds like you have a threading problem or a wild point somewhere else in your program. Try printing the value of the mutex pointer. Try having another thread that simply locks the mutex and then prints to a log file the time and that the lock was successful, then unlocks the mutex. I suspect the problem is not where you are looking.
Also, as other have said here, your best bet is to create a very small test program that demonstrates the problem and post it here. Chances are you won't be able to get that small program to demonstrate the error. Then slowly add all of your original code into the small program until the error returns. If it returns, you now know what caused the problem. If it doesn't return, you're done.
Related
In one of my courses, my professor asks us to implement a small program that spawns 5 threads and use a mutex to check if it's the threads respective turn. However, he also requested that we use a condition variable to avoid busy waiting for their turn.
From first glance this doesn't make much sense to me, because we cannot guarantee that any signal is going to wake up the correct thread. It seems like this is bound to be a deadlock unless the infinitely unlikely scenario occurs that the correct sleeping thread is woken up every time. Am I missing something?
Your professor gave you the necessary information to complete the task.
From first glance this doesn't make much sense to me, because we cannot guarantee that any signal is going to wake up the correct thread.
Yes, the setup you are thinking of is used when you don't care which thread is waked up, e.g. when you have a worker pool and you just need a free thread, any free thread to assign the work to.
But if you think about it you can see you can create setups with locks and condition variables that result in your desired behavior, i.e. waking up a specific thread.
Hint: a condition variable has notify_all
Hint: or, alternatively, you can have more than 1 condition variable.
Think a bit about it and try different things.
This really is two questions, but I suppose it's better they be combined.
We're working on a client that uses asynchronous TCP connection. The idea is that the program will block until certain message is received from the server, which will invoke a SIGPOLL handler. We are using a busy waiting loop, basically:
var = 1
while (var) usleep(100);
//...and somewhere else
void sigpoll_handler(int signum){
......
var = 0;
......
}
We would like to use something more reliable instead, like a semaphore. The thing is, when a thread is blocked on a semaphore, will the signal get through still? Especially considering that signals get delivered when it switches back to user level; if the process is off the runqueue, how will it happen?
Side question (just out of curiosity):
Without the "usleep(100)" the program never progresses past the while loop, although I can verify the variable was set in the handler. Why is that? Printing changes its behaviour too.
Cheers!
[too long for a comment]
Accessing var from inside the signal handler invokes undefined behaviour (at least for a POSIX conforming system).
From the related POSIX specification:
[...] if the process is single-threaded and a signal handler is executed [...] the behavior is undefined if the signal handler refers to any object [...] with static storage duration other than by assigning a value to an object declared as volatile sig_atomic_t [...]
So var shall be defined:
volatile sig_atomic_t var;
The busy waiting while-loop, can be replaced by a single call to a blocking pause(), as it will return on reception of the signal.
From the related POSIX specification:
The pause() function shall suspend the calling thread until delivery of a signal whose action is either to execute a signal-catching function or to terminate the process.
Using pause(), btw, will make the use of any global flag like var redundant, to not say needless.
Short answer: yes, the signal will get through fine with a good implementation.
If you're going to be using a semaphore to control the flow of the program, you'll want to have the listening be on one child with the actual data processing be on another. This will then put the concurrency fairness in the hands of the OS which will make sure your signal listening thread gets a chance to check for a signal with some regularity. It shouldn't ever be really "off the runqueue," but cycling through positions on the runqueue instead.
If it helps you to think about it, what you have right now seems to basically be a a very rough implementation of a semaphore on its own -- a shared variable whose value will stop one block of code from executing until another code block clears it. There isn't anything inherently paralyzing about a semaphore on a system level.
I kind of wonder why whatever function you're using to listen for the SIGPOLL isn't doing its own blocking, though. Most of those utilities that I've seen will stop their calling thread until they return a value. Basically they handle the concurrency for you and you can code as if you were dealing with a normal synchronous program.
With regards to the usleep loop: I'd have to look at what the optimizer's doing, but I think there are basically two possibilities. I think it's unlikely, but it could be that the no-body loop is compiling into something that isn't actually checking for a value change and is instead just looping. More likely to me would be that the lack of any body steps is messing up the underlying concurrency handling, and the loop is executing so quickly that nothing else is getting a chance to run -- the queue is being flooded by loop iterations and your signal processsing can't get a word in edgewise. You could try just watching it for a few hours to see if anything changes; theoretically if it's just a concurrency problem then the random factor involved could clear the block on its own with a few billion chances.
I have a situation as follows:
int funcA()
{
/*There will call funcB*/
funcB();
}
funcB() maybe last for a long time. And if I find it has been running for over 5 minutes, I want to abort funcB() and continue to do other thing.
How can I do this?
One way to do this is to measure the time elapsed within funcB() since entering, e.g. if you have a loop in funcB(). Ideally, your function returns a value that indicates success or early termination, so funcA() has a way to know if funcB() completed.
Another way is to run funcB() in its own thread. If your main thread determines that 5 min have passed, it can terminate the thread that is executing funcB().
If you are a beginner, why not create a new process by using fork(). Then start timing within the new process and then terminate the process if it exceeds 5 minutes. Even though in most cases threads are better to use, it's easier for beginners to create a new process.
You should code a feature in funcB so it will know to return.. Anything else is somewhat unsafe, if funcB for example writes to files. There are many ways to do this. I'm assuming you have a loop in funcB, which you want to abort. If you have something else, like blocking IO operation, you have to do this a bit differently.
If you have single thread, you could code the abort logic directly into funcB. You could also give function pointer argument for funcB, which then calls the function every loop round to see if it could abort. That way you can more easily have different abort conditions.
If you have multiple threads, you should use an atomic flag variable, which you set from other thread when you want funcB to abort, and in funcB loop you then test it. This is the most common way to twll orher thread running a loop to quit.
Addition: If you are going to abort file operations, it's possible to do it safely if you do a few things:
The function must do writes to temporary file (at same disk partition), and then close it and use rename operation (which is atomic at OS level when files are in same partition) to create/replace the final file. That way, if operation is aborted, the final file will not be left in corrupted state.
The caller must have the file handle or file descriptor of the temporary file, so it can close the file if file operation was aborted while file was open. If file operation happens in another process, which is killed, then that will close all file handles and this is not needed.
Caller should also always try to remove the temp file, in case the aborted function/thread/process did not have a chance to rename it to final name or remove it.
Addition 2: In Unix/Linux you can use alarm() function. See this: Simple Signals - C programming and alarm function
I used to get a trouble with pthread_exit(). I know there is no way to use pthread_exit() in a way like
pthread_exit(&some_local_variable);
We always need to use pthread_exit() like:
pthread_exit("Thread Exit Message or something necessary information");
I once coded a simple program for testing purpose.
I made four thread functions for addition, subtraction, multiplication and division of two integers, respectively. Then while performing these operations on four different threads, I tried to return the result of the operation by pthread_exit(). What I mean is something like:
pthread_exit(&add_result);
When I ran the code in CentOS 6, I got the desired result (i.e., garbage values from all the threads) as pthread_exit() cannot be used like that. But, I got confused. Because for the first time, I ran that code in Ubuntu 11.10 and got three absolutely correct result(correct result of the operation) from three threads and garbage value from one thread. This confused me because why three threads are giving correct result of operation?
Moreover, I used different sleep times for those threads. I found that the thread having least sleep time gave the garbage value.
As gcc is the compiler for both these operating systems, why one system has bugs like this?
It confuses novice programmers like me. If it is not a bug, can anyone explain it to me why is this happening?
I think your answer is in pthread_exit doc. You say that you returned a pointer on add_result, which seems to be a local variable.
Here is the quote of the doc that might answer:
After a thread has terminated, the result of access to local (auto)
variables of the thread is undefined. Thus,
references to local variables of the exiting thread should not be used for the pthread_exit() value_ptr parameter
value.
You may use the void* argument to the threaded function to use a structure, which should contain the actual result of your operation.
pthread_exit just takes a pointer to a void. If you pass the address of a variable local to the thread, sometimes that memory will have been reused for something else. Sometimes it will still be there. There's no guarantee that after a thread exits, some part of the system will go and make sure that all of the memory it was using is set to garbage values.
It's not a bug - the system is doing exactly what you ask it.
Bonus related answer - Can a local variable's memory be accessed outside its scope?
The only requirement for pthread_exit(foo) is that foo points to something which lives long enough. Local variables don't, malloc'ed memory does.
I know there is one for multi processes
waitpid(-1,WNOHANG,NULL)
that is non-blocking function call to check if there is any child process currently working on
But is there any similar lib function to check for multithread?
All i want to do is check if there is any thread currently on, if not reset some global values.
that is non-blocking function call to check if there is any child process currently working on
Wrong. That is a call to check if there is any child process not yet terminated. And it not only checks but also reaps a terminated child, if any. Children might be otherwise in any possible state, like hanging in a deadlock (what on my book is far from being working).
All i want to do is check if there is any thread currently on, if not reset some global values.
Probably you should post here as a question why you want to do it. It sounds that you do something terribly wrong.
If you do not do already pthread_join() for your threads, that means that your threads already do pthread_detach(). If you had no problems adding to your threads pthread_detach() I think there would be no problem to add some extra code to threads to identify that they have (almost) terminated (e.g. sem_post()) so that main() can notice that a thread had terminated (e.g. by calling sem_trylock()).
If portability isn't a requirement, then one can also try query OS number of threads of the process periodically.
Though it is still IMO wrong to have in a program some threads, with undefined life cycle, without any proper sync with main thread.
You could just save the handle of a thread and have a function to check if it is still running. I'm not sure if theres a function but this should work.
pthread_kill(pid, 0) where pid is the thread id that pthread_create has returned can tell you if a thread is still alive. (That is how I understand your question)
It returns 0 if the thread is still alive and an error code otherwise.
I asked myself something quite similar:
POSIX API call to list all the pthreads running in a process
In your case I would just wrapped up ps -eLF.