void cleanupHandler(void *arg) {
printf("In the cleanup handler\n");
}
void *Thread(void *string) {
int i;
int o_state;
int o_type;
pthread_cleanup_push(cleanupHandler, NULL);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &o_state);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &o_type);
puts("1 Hello World");
pthread_setcancelstate(o_state, &o_state);
puts("2 Hello World");
pthread_cleanup_pop(0);
pthread_exit(NULL);
}
int main() {
pthread_t th;
int rc;
rc = pthread_create(&th, NULL, Thread, NULL);
pthread_cancel(th);
pthread_exit(NULL);
}
I was wondering what the output of this code would be and in what order they would happen. Yes, this is a practice test question for an exam I have in 6 hours. Any help would be greatly appreciated. There are no office hours today as all of the TA's for my college are busy with their own finals.
Thanks
Here are the man pages you need to understand the problem they will be putting on the exam (which most certainly won't be the exact problem above.) So you need to understand what each of those functions does.
http://man7.org/linux/man-pages/man3/pthread_cleanup_push.3.html
http://man7.org/linux/man-pages/man3/pthread_setcanceltype.3.html,
http://man7.org/linux/man-pages/man3/pthread_cancel.3.html
http://man7.org/linux/man-pages/man3/pthread_exit.3.html
cleanup_push pushs a handler on a stack of functions that will be called if the calling thread is cancelled or exits.
setcancelstate temporarily locks out cancels (so that you can call setcanceltype atomically without weirdness happening.)
setcanceltype allows/disallows asynchronous cancellation notification.
cancel actually attempts to cancel the other thread.
exit exits from the calling thread.
You also need to understand whether pthread_setcancelstate is a cancellation point. You will find that information either on the above man pages or on http://man7.org/linux/man-pages/man7/pthreads.7.html.
In this question (and presumably the similar one that will be on your exam), you need to enumerate all possible interleavings of calls to these functions between the two threads.
1 Hello World
2 Hello World
Why not just compile it and run it? This version compiles and runs.
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void cleanupHandler(void *arg) {
printf("In the cleanup handler\n");
}
void* Thread(void *string) {
int i;
int o_state;
int o_type;
sleep(1);
pthread_cleanup_push(cleanupHandler, NULL);
sleep(1);//Note that when you uncomment lines, you should uncomment them in order.
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &o_state);
sleep(1);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &o_type);
puts("1 Hello World");
sleep(1);
pthread_setcancelstate(o_state, &o_state);
sleep(1);
puts("2 Hello World");
pthread_cleanup_pop(0);
pthread_exit(NULL);
}
int main() {
pthread_t th;
int rc;
rc = pthread_create(&th, NULL, Thread, NULL);
pthread_cancel(th);
pthread_exit(NULL);
}
Related
How are you?
I am going to fix the segmentation fault in a worker thread on Ubuntu 18.04.
My code is the following.
#include <thread>
#include <signal.h>
#include <string.h>
#include <pthread.h>
#include <opencv2/opencv.hpp>
void sigsegv_handler(int signum, siginfo_t *info, void *data)
{
printf("The thread was crashed\n");
pthread_exit(NULL);
}
void sleep_ms(int milliseconds)
{
#ifdef WIN32
Sleep(milliseconds);
#elif _POSIX_C_SOURCE >= 199309L
struct timespec ts;
ts.tv_sec = milliseconds / 1000;
ts.tv_nsec = (milliseconds % 1000) * 1000000;
nanosleep(&ts, NULL);
#else
usleep(milliseconds * 1000);
#endif
}
void thread_func(int i)
{
if(i == 3)
{
int *p = 0;
*p = 10;
}
printf("A new thread ran successfully\n");
}
int main()
{
/* Set SIGSEGV handler. */
struct sigaction handler;
sigemptyset(&handler.sa_mask);
handler.sa_sigaction = &sigsegv_handler;
handler.sa_flags = SA_SIGINFO;
if (sigaction(SIGSEGV, &handler, NULL) == -1)
fprintf(stderr, "Cannot set SIGSEGV handler: %s.\n", strerror(errno));
int i = 0;
while(1)
{
std::thread writer_thread(thread_func, i);
writer_thread.detach();
sleep_ms(1000);
printf("%d\n", i++);
}
return 0;
}
The code works well.
The output of this code are following.
A new thread ran successfully
0
A new thread ran successfully
1
A new thread ran successfully
2
The thread was crashed
3
A new thread ran successfully
4
A new thread ran successfully
5
A new thread ran successfully
6
A new thread ran successfully
7
But if I change the function "thread_func" as the following, the program is crashed.
void thread_func(int i)
{
if(i == 3)
{
int *p = 0;
*p = 10;
}
cv::Mat img(100, 100, CV_8UC3); // newly inserted
cv::resize(img, img, cv::Size(200, 200)); //newly inserted
printf("A new thread ran successfully\n");
}
The error messages are the following.
A new thread ran successfully
0
A new thread ran successfully
1
A new thread ran successfully
2
The thread was crashed
terminate called without an active exception
Aborted (core dumped)
Of course, I am sure there is no issue in OpenCV module.
Could u help me to fix this issue?
Thanks
The simple answer is you can't do this:
void sigsegv_handler(int signum, siginfo_t *info, void *data)
{
printf("The thread was crashed\n");
pthread_exit(NULL);
}
First, per 7.1.4 Use of library functions, paragraph 4 of the C 11 standard:
The functions in the standard library are not guaranteed to be reentrant and may modify objects with static or thread storage duration.
Or, as summarized by footnote 188:
Thus, a signal handler cannot, in general, call standard library functions.
So, absent specific guarantees from your platform about what functions you can safely call from a signal handler, you can not make any function calls from within a signal handler.
But since you are calling pthread_exit(), assuming you're using a POSIX system, POSIX does provide some guarantees about what functions you can call, termed "async-signal-safe, at https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04_03. The Linux-specific list can be found at https://man7.org/linux/man-pages/man7/signal-safety.7.html
Note that neither printf() nor pthread_exit() are on either list.
Calling printf() from within a SIGSEGV signal handler is going to be dangerous - most implementations of printf() will use some form of malloc()/free(), and SIGSEGV is often a result of a malloc()/new/free()/delete operation encountering that corrupted heap. Heap operations tend to happen under a lock of some sort to protect against simultaneous modification of heap state, so calling printf() in a SIGSEGV handler of all things creates a huge deadlock risk.
And pthread_exit() will also cause huge problems - it's not only trying to change process state in the process's address space, it's trying to make changes to the process state in kernel space. From within a signal handler, that's simply not going to work.
Suppose my main function calls an external function veryslow()
int main(){... veryslow();..}
Now I would like to the invocation part of very_slow in main, so that veryslow terminates if it runs out of a time bound. Something like this
int main(){... call_with_timeout(veryslow, 0.1);...}
What is a simple way to achieve that? My OS is Ubuntu 16.04.
You can call this function in a new thread, and set a timeout to terminate the thread, it will end this function call.
A POSIX example would be:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
pthread_t tid;
// Your very slow function, it will finish running after 5 seconds, and print Exit message.
// But if we terminate the thread in 3 seconds, Exit message will not print.
void * veryslow(void *arg)
{
fprintf(stdout, "Enter veryslow...\n");
sleep(5);
fprintf(stdout, "Exit veryslow...\n");
return nullptr;
}
void alarm_handler(int a)
{
fprintf(stdout, "Enter alarm_handler...\n");
pthread_cancel(tid); // terminate thread
}
int main()
{
pthread_create(&tid, nullptr, veryslow, nullptr);
signal(SIGALRM, alarm_handler);
alarm(3); // Run alarm_handler after 3 seconds, and terminate thread in it
pthread_join(tid, nullptr); // Wait for thread finish
return 0;
}
You can use future with timeout.
std::future<int> future = std::async(std::launch::async, [](){
veryslow();
});
std::future_status status;
status = future.wait_for(std::chrono::milliseconds(100));
if (status == std::future_status::timeout) {
// verySlow() is not complete.
} else if (status == std::future_status::ready) {
// verySlow() is complete.
// Get result from future (if there's a need)
auto ret = future.get();
}
Note that there's no built-in way to cancel an async task. You will have to implement that inside verySlow itself.
See here for more:
http://en.cppreference.com/w/cpp/thread/future/wait_for
i would pass a pointer to an interface into the function and ask for one back. with this i would enable two way communication to perform all necessary tasks--including timeout and timeout notification.
I want to know if its possible to interrupt main thread and ask it to execute some callback. The main thread should continue with what it was doing after completing the callback.
For instance, we have 2 threads t1 and m1 (main thread). t1 will interrupt m1 (main thread) and ask it to call a function with some parameters. The m1 (main thread) will stop doing what it was doing before and will start executing the function. The after finishing the function, it will get back to what it was doing earlier.
I want to replicate what hardware interrupt does. I have one thread that reads data from a file. Then it should ask main thread to call a function. Main thread will be doing something. It should stop doing it and start executing the function. After completing it, main thread should continue with what it was doing
A clean way I think would be to have a queue of operations that t1 adds to, that t2 checks at points in its processing loop where it is safe to start doing something else.
On POSIX systems, you can use signals. For example, the following starts a second thread and, while the main thread is doing other work, this second thread sends it a SIGUSR1 signal. The main thread handles it and resumes operation.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <signal.h>
void* other_thread(void* main_thread) {
printf("other_thread: %x\n", pthread_self());
usleep(250*1000);
printf("sending SIGUSR1 to main thread...\n");
pthread_kill((pthread_t) main_thread, SIGUSR1);
return NULL;
}
void my_handler(int signal) {
printf("my_handler: %x\n", pthread_self());
sleep(2);
printf("back to main\n");
}
int main(int argc, char**argv) {
signal(SIGUSR1, my_handler);
pthread_t thread1;
pthread_create(&thread1, NULL, other_thread, pthread_self());
printf("main: %x\n", pthread_self());
int x = 0;
while (1) {
// sleep(1), or do some work, or:
x++;
if (x % 10000000 == 0) printf("boo\n");
}
}
Can somebody please explain to me why this simple code leaks memory?
I believe that since pthreads are created with detached state their resources should be released inmediatly after it's termination, but it's not the case.
My environment is Qt5.2.
#include <QCoreApplication>
#include <windows.h>
void *threadFunc( void *arg )
{
printf("#");
pthread_exit(NULL);
}
int main()
{
pthread_t thread;
pthread_attr_t attr;
while(1)
{
printf("\nStarting threads...\n");
for(int idx=0;idx<100;idx++)
{
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create( &thread, &attr, &threadFunc, NULL);
pthread_attr_destroy ( &attr );
}
printf("\nSleeping 10 seconds...\n");
Sleep(10000);
}
}
UPDATE:
I discovered that if I add a slight delay of 5 milliseconds inside the for loop the leak is WAY slower:
for(int idx=0;idx<100;idx++)
{
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create( &thread, &attr, &threadFunc, NULL);
pthread_attr_destroy ( &attr );
Sleep(5); /// <--- 5 MILLISECONDS DELAY ///
}
This is freaking me out, could somebody please tell me what is happening? How this slight delay may produce such a significant change? (or alter the behavior in any way)
Any advice would be greatly appreciated.
Thanks.
UPDATE2:
This leak was observed on Windows platforms (W7 and XP), no leak was observed on Linux platforms (thank you #MichaelGoren)
I checked the program with slight modifications on windows using cygwin, and memory consumption was steady. So it must be a qt issue; the pthread library on cygwin works fine without leaking.
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
void *threadFunc( void *arg )
{
printf("#");
pthread_exit(NULL);
}
int main()
{
pthread_t thread;
pthread_attr_t attr;
int idx;
while(1)
{
printf("\nStarting threads...\n");
for(idx=0;idx<100;idx++)
{
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create( &thread, &attr, &threadFunc, NULL);
pthread_attr_destroy ( &attr );
}
printf("\nSleeping 10 seconds...\n");
//Sleep(10000);
sleep(10);
}
}
Compiler optimizations or the OS it self can decide to do loop unrolling. That is your for loop has a constant bound (100 here). Since there is no explicit synchronization to prevent it, a newly created, detached thread can die and have its thread ID reassigned to another new thread before its creator returns from pthread_create() due to this unrolling. The next iteration is already started before the thread was actually destroyed.
This also explains why your added slight delay has less issues; one iteration takes longer and hence the thread functions can actually finish in more cases and hence the threads are actually terminated most of the time.
A possible fix would be to disable compiler optimizations, or add synchronization; that is, you check whether the thread still exist, at the end of the code, if it does you'll have to wait for the function to finish.
A more tricky way would be to use mutexes; you let the thread claim a resource at creation and by definition of PTHREAD_CREATE_DETACHED this resource is automatically released when the thread is exited, hence you can use try_lock to test whether the thread is actually finished. Note that I haven't tested this approach so I'm not actually sure whether PTHREAD_CREATE_DETACHED actually is working according to its definition...
Concept:
pthread_mutex_t mutex;
void *threadFunc( void *arg )
{
printf("#");
pthread_mutex_lock(&mutex);
pthread_exit(NULL);
}
for(int idx=0;idx<100;idx++)
{
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create( &thread, &attr, &threadFunc, NULL);
pthread_attr_destroy ( &attr );
pthread_mutex_lock(&mutex); //will block untill "destroy" has released the mutex
pthread_mutex_unlock(&mutex);
}
The delay can induce a large change in behavior because it gives the thread time to exit! Of course how your pthread library is implemented is also a factor here. I suspect it is using a 'free list' optimization.
If you create 1000 threads all at once, then the library allocates memory for them all before any significant number of those threads can exit.
If as in your second code sample you let the previous thread run and probably exit before you start a new thread, then your thread library can reuse that thread's allocated memory or data structures which it now knows are no longer needed and it is now probably holding in a free list just in case someone creates a thread again and it can efficiently recycle the memory.
It has nothing to do with compiler optimisations. Code is fine. Problem could be
a) Windows itself.
b) Qt implementation of pthread_create() with detached attributes
Checking for (a): Try to create many fast detached threads using Windows _beginthreadex directly and see if you get the same picture. Note: CloseHandle(thread_handle) as soon as _beginthreaex returns to make it detached.
Checking for (b): Trace which function Qt uses to create threads. If it is _beginthread then there is your answer. If it is _beginthreadex, then Qt is doing the right thing and you need to check if Qt closes the thread handle handle immediately. If it does not then that is the cause.
cheers
UPDATE 2
Qt5.2.0 does not provide pthreads API and is unlikely responsible for the observed leak.
I wrapped native windows api to see how the code runs without pthread library. You can include this fragment right after includes:
#include <process.h>
#define PTHREAD_CREATE_JOINABLE 0
#define PTHREAD_CREATE_DETACHED 1
typedef struct { int detachstate; } pthread_attr_t;
typedef HANDLE pthread_t;
_declspec(noreturn) void pthread_exit(void *retval)
{
static_assert(sizeof(unsigned) == sizeof(void*), "Modify code");
_endthreadex((unsigned)retval);
}
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
{
attr->detachstate = detachstate;
return 0;
}
int pthread_attr_init(pthread_attr_t *attr)
{
attr->detachstate = PTHREAD_CREATE_JOINABLE;
return 0;
}
int pthread_attr_destroy(pthread_attr_t *attr)
{
(void)attr;
return 0;
}
typedef struct {
void *(*start_routine)(void *arg);
void *arg;
} winapi_caller_args;
unsigned __stdcall winapi_caller(void *arglist)
{
winapi_caller_args *list = (winapi_caller_args *)arglist;
void *(*start_routine)(void *arg) = list->start_routine;
void *arg = list->arg;
free(list);
static_assert(sizeof(unsigned) == sizeof(void*), "Modify code");
return (unsigned)start_routine(arg);
}
int pthread_create( pthread_t *thread, pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg)
{
winapi_caller_args *list;
list = (winapi_caller_args *)malloc(sizeof *list);
if (list == NULL)
return EAGAIN;
list->start_routine = start_routine;
list->arg = arg;
*thread = (HANDLE)_beginthreadex(NULL, 0, winapi_caller, list, 0, NULL);
if (*thread == 0) {
free(list);
return errno;
}
if (attr->detachstate == PTHREAD_CREATE_DETACHED)
CloseHandle(*thread);
return 0;
}
With Sleep() line commented out it works OK without leaks. Run time = 1hr approx.
If the code with Sleep line commented out is calling Pthreads-win32 2.9.1 library (prebuilt for MSVC) then the program stops spawning new threads and stops responding after 5..10 minutes.
Test environment: XP Home, MSVC 2010 Expresss, Qt5.2.0 qmake etc.
You forgot to join your thread (even if they are finished already).
Correct code should be:
pthread_t arr[100];
for(int idx=0;idx<100;idx++)
{
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create( &arr[idx], &attr, &threadFunc, NULL);
pthread_attr_destroy ( &attr );
}
Sleep(2000);
for(int idx=0;idx<100;idx++)
{
pthread_join(arr[idx]);
}
Note from man page:
Failure to join with a thread that is joinable (i.e., one that is not detached), produces a "zombie thread". Avoid doing this, since each zombie thread consumes some system resources, and when enough zombie threads have
accumulated, it will no longer be possible to create new threads (or processes).
I'm developing an application For OpenSUSE 12.1.
This application has a main thread and other two threads running instances of the same functions. I'm trying to use pthread_barrier to synchronize all threads but I'm having some problems:
When I put the derived threads to sleep, they will never wake up for some reason.
(in the case when I remove the sleep from the other threads, throwing CPU usage to the sky) In some point all the threads reach pthread_barrier_wait() but none of them continues execution after that.
Here's some pseudo code trying to illustrate what I'm doing.
pthread_barrier_t barrier;
int main(void)
{
pthread_barrier_init(&barrier, NULL , 3);
pthread_create(&thread_id1, NULL,&thread_func, (void*) ¶ms1);
pthread_create(&thread_id2v, NULL,&thread_func, (void*) ¶ms2);
while(1)
{
doSomeWork();
nanosleep(&t1, &t2);
pthread_barrier_wait(&barrier);
doSomeMoreWork();
}
}
void *thread_func(void *params)
{
init_thread(params);
while(1)
{
nanosleep(&t1, &t2);
doAnotherWork();
pthread_barrier_wait(&barrier);
}
}
I don't think it has to do with the barrier as you've presented it in the pseudocode. I'm making an assumption that your glibc is approximately the same as my machine. I compiled roughly your pseudo-code and it's running like I expect: the threads do some work, the main thread does some work, they all reach the barrier and then loop.
Can you comment more about any other synchronization methods or what the work functions are?
This is the the example program I'm using:
#include <pthread.h>
#include <stdio.h>
#include <time.h>
struct timespec req = {1,0}; //{.tv_sec = 1, .tv_nsec = 0};
struct timespec rem = {0,0}; //{.tv_sec = 0, .tv_nsec = 0};
pthread_barrier_t barrier;
void *thread_func(void *params) {
long int name;
name = (long int)params;
while(1) {
printf("This is thread %ld\n", name);
nanosleep(&req, &rem);
pthread_barrier_wait(&barrier);
printf("More work from %ld\n", name);
}
}
int main(void)
{
pthread_t th1, th2;
pthread_barrier_init(&barrier, NULL , 3);
pthread_create(&th1, NULL, &thread_func, (void*)1);
pthread_create(&th2, NULL, &thread_func, (void*)2);
while(1) {
nanosleep(&req, &rem);
printf("This is the parent\n\n");
pthread_barrier_wait(&barrier);
}
return 0;
}
I would suggest to use condition variables in order to synchronize threads.
Here some website about how to do it i hope it helps.
http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html