Reputation: 1
I should write a program which creates a thread with printing text routine, and after two seconds of executing this thread should be canceled and the message of cancelling should be printed. The task condition is such that phtread_cleanup_push(3C) should be used for this purpose.
I create a thread by pthread_create() calling with an infinity routine of text printing. The thread is created with default values of cancelation state and cancelation type, so the cancelation of the created thread occurs when the thread reaches the cancelation point. The main thread waits two seconds and then calls pthread_cancel(3C) to the child thread.
The created thread is printing the text with 0,1 second time interval using usleep(). Also I pasted pthread_testcancel() call inside infinity loop. So we have two cancelation point inside the loop: one is the system defined - usleep() and the second is created by calling pthread_testcancel().
Before the infinity loop I pasted the pthread_cleanup_push() with another printing text routine. And after the infinity loop I pasted pthread_cleanup_pop() statement, because both of this statements are implemented as the macro and according to the official documentation they should be in the same lexical scope.
Unfortunately cleanup handler routine doesn't executed. Child thread is canceling but no message about it is printing. I've been searching the answer for my problem for a long time, but nothing I've found was similar to my problem, so I'll be very thankful for any recommendation about solving my problem.
Here is my code below and it's output. I am using Oracle VM Virtual Box on Windows 10 (64-bit) on which Oracle Solaris-10 (64-bit) is running. I compile my program using bash 3.2 with the command:
gcc -o lab5 -threads -lpthread -std=c99 lab5.c
code:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#define SUCCESS 0
#define FAILED 1
#define WAIT_TIME 2
#define PRINT_DELTA_TIME 1 * 100000 // in microseconds
char* printing_text = "Child thread text\n"; // this text will be printed by child thread
char* termination_text = "Child thread is terminated\n";
void cleanup_handler(void* arg) {
printf(termination_text);
}
// infinity routine of printing text
void *print_text() {
pthread_cleanup_push(cleanup_handler, NULL); // push cleanup routine to the stack
while (1) {
pthread_testcancel();
printf("%s\n", printing_text);
usleep(PRINT_DELTA_TIME);
}
pthread_cleanup_pop(1);
return NULL;
}
// cancel a thread with exception handling
int try_cancel_thread(pthread_t *thread) {
int code = pthread_cancel(*thread);
if (code != SUCCESS) {
char* error_message = strerror(code);
fprintf(stderr, "%s%s\n", "can't cancel a child thread:", error_message);
return FAILED;
}
return SUCCESS;
}
// creating a thread with exception handling
int try_create_thread(pthread_t *thread) {
int code = pthread_create(thread, NULL, print_text, NULL);
if (code != SUCCESS) {
char* error_message = strerror(code);
fprintf(stderr, "%s%s\n", "can't create a child thread:", error_message);
return FAILED;
}
return SUCCESS;
}
int main() {
pthread_t child_thread;
if (try_create_thread(&child_thread) == FAILED) {return FAILED;}
sleep(WAIT_TIME);
if (try_cancel_thread(&child_thread) == FAILED) {return FAILED;}
printf("the execution is succefully completed\n");
return SUCCESS;
}
#undef SUCCESS
#undef FAILED
#undef WAIT_TIME
#undef PRINT_DELTA_TIME
output:
Child thread text
Child thread text
Child thread text
Child thread text
Child thread text
Child thread text
Child thread text
Child thread text
Child thread text
Child thread text
Child thread text
Child thread text
Child thread text
Child thread text
Child thread text
Child thread text
the execution is succefully completed
Upvotes: 0
Views: 81