#include <pthread.h>
#include <stdio.h>
#define FAILURE 0
#define SUCCESS 1
#define UNS32 unsigned int
#define m_ERROR(format, args...) printf(format, ## args);//fflush(stdout);
static pthread_t g_pthread_wait;
static pthread_t g_pthread_signal;
static pthread_t g_pthread_mt;
pthread_mutex_t g_pthread_mutex;
pthread_cond_t g_pthread_cond;
UNS32 pthread_initialize_cond(void){
if ( (pthread_cond_init(&g_pthread_cond, NULL)) != 0 ) {
m_ERROR("/t!!! ERROR : pthread_cond_init !!!/n");
return FAILURE;
}
return SUCCESS;
}
UNS32 pthread_initialize_mutex(void){
if ( (pthread_mutex_init(&g_pthread_mutex, NULL)) != 0 ) {
m_ERROR("/t!!! ERROR : pthread_mutex_init !!!/n");
return FAILURE;
}
return SUCCESS;
}
void pthread_wait(void *args){
pthread_detach(pthread_self());
pthread_mutex_lock(&g_pthread_mutex);
printf("pthread_cond_wait_in/n");
pthread_cond_wait(&g_pthread_cond, &g_pthread_mutex);
printf("pthread_cond_wait_out/n");
while(1) {
printf("wait_while/n");
sleep(1);
}
pthread_exit(NULL);
}
void pthread_signal(void *args){
pthread_detach(pthread_self());
pthread_cond_signal(&g_pthread_cond);
printf("pthread_cond_signal_out/n");
pthread_exit(NULL);
}
void pthread_mt(void *args) {
printf("pthread_cancel_in /n");
pthread_cancel(g_pthread_wait);
printf("pthread_cancel_out /n");
pthread_mutex_unlock(&g_pthread_mutex);
pthread_mutex_lock(&g_pthread_mutex);
printf("pthread_mt_lock/n");
}
int main() {
pthread_initialize_cond();
pthread_initialize_mutex();
if (pthread_create(&g_pthread_wait , NULL, (void * (*)(void *)) pthread_wait, NULL) !=0) {
return FAILURE;
}
sleep(1);
if (pthread_create(&g_pthread_signal , NULL, (void * (*)(void *)) pthread_signal, NULL) !=0) {
return FAILURE;
}
sleep(5);
if (pthread_create(&g_pthread_mt , NULL, (void * (*)(void *)) pthread_mt, NULL) !=0) {
return FAILURE;
}
printf("while!/n");
while(1);
}
pthread_cancel(g_pthread_wait);的作用是将pthread_wait线程杀掉。
打印结果为:
pthread_cond_wait_in
pthread_cond_signal_out
pthread_cond_wait_out
wait_while
wait_while
wait_while
wait_while
wait_while
while!
pthread_cancel_in
pthread_cancel_out
pthread_mt_lock
如果将 pthread_mutex_unlock(&g_pthread_mutex);注释掉的话,那么就不会打印出pthread_mt_lock这条语句。
分析:
1.pthread_wait先执行,打印pthread_cond_wait_in后,pthread_cond_wait函数被调用,等待g_pthread_cond条件,并解
锁;
2.sleep 1秒后,pthread_signal执行,pthread_cond_signal函数被调用后,打印pthread_cond_signal_out,线程退出,则
pthread_cond_wait被唤醒,加锁之后进入while循环;
3.sleep 5秒后,pthread_mt执行,打印pthread_cancel_in 后,调用pthread_cancel将pthread_wait线程杀掉,因为
pthread_cond_wait返回时,加锁了,所以pthread_wait被杀死之后,锁没有被解开,如果不调用
pthread_mutex_unlock解锁,下面的加锁函数就阻塞了,因此就打印不出pthread_mt_lock了。
补充:
被杀线程可以使用如下代码,控制本线程被杀死时的动作
int state = 0; int type = 0;
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &state);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &type);
pthread_setcancelstate函数
pthread_setcancelstate函数的作用是设置本线程是否允许被其他线程关闭,原型如下:
int pthread_setcancelstate(int state, int *oldstate);
参数state:可以取值PTHREAD_CANCEL_ENABLE或PTHREAD_CANCEL_DISABLE,前者表示允许被其他线程关闭,后者表示不允许,默认为前者;
参数oldstate:返回设置之前的本属性值;
返回值:0成功,非0失败;
pthread_setcanceltype函数
pthread_setcanceltype函数的作用是设置本线程被其他线程关闭时,以什么方式关闭,原型如下:
int pthread_setcanceltype(int type, int *oldtype);
参数type:PTHREAD_CANCEL_ASYNCHRONOUS或PTHREAD_CANCEL_DEFERRED,前者表示被立刻关闭,后者表示等线程被阻塞时再关闭,默认为后者;
参数oldtype:返回设置之前的本属性值;
返回值:0成功,非0失败;
例子:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
void *thread_function(void *arg);
int main() {
int res;
pthread_t a_thread;
void *thread_result;
res = pthread_create(&a_thread, NULL, thread_function, NULL);
if (res != 0) {
perror("Thread creation failed");
exit(EXIT_FAILURE);
}
sleep(3);
printf("Cancelling thread.../n");
res = pthread_cancel(a_thread);
if (res != 0) {
perror("Thread cancelation failed");
exit(EXIT_FAILURE);
}
printf("Waiting for thread to finish.../n");
res = pthread_join(a_thread, &thread_result);
if (res != 0) {
perror("Thread join failed");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
void *thread_function(void *arg) {
int i, res;
res = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
if (res != 0) {
perror("Thread pthread_setcancelstate failed");
exit(EXIT_FAILURE);
}
res = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
if (res != 0) {
perror("Thread pthread_setcanceltype failed");
exit(EXIT_FAILURE);
}
printf("thread_function is running/n");
for(i = 0; i < 10; i++) {
printf("Thread is still running (%d).../n", i);
sleep(1);
}
pthread_exit(0);
}
运行结果:
thread_function is running
Thread is still running (0)...
Thread is still running (1)...
Thread is still running (2)...
Cancelling thread...
Waiting for thread to finish...
Thread is still running (3)...