【Linux 线程】常用线程函数复习《二》

时间:2023-03-10 00:24:55
【Linux 线程】常用线程函数复习《二》

1、函数pthread_join

 /*************************************************************************
> File Name: pthread_join1.c
> Summary: pthread_join函数的基本用法
> Author: xuelisheng
> Created Time: 2018年12月13日
************************************************************************/ #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h> struct thrd
{
int var;
char str[];
}; void *tfn(void *arg)
{
struct thrd *tval;
tval = malloc(sizeof(tval)); tval->var = ;
strcpy(tval->str, "hello xls");
return (void *)tval;
} int main()
{
pthread_t tid;
struct thrd *retval;
int ret = pthread_create(&tid, NULL, tfn, NULL);
if(ret != )
{
printf("create thread fail\n");
}
/*
函数pthread_join用来等待一个线程的结束,线程间同步的操作。头文件 : #include <pthread.h>
函数定义: int pthread_join(pthread_t thread, void **retval);
描述 :pthread_join()函数,以阻塞的方式等待thread指定的线程结束。当函数返回时,被等待线程的资源被收回。如果线程已经结束,那么该函数会立即返回。并且thread指定的线程必须是joinable的。
参数 :thread: 线程标识符,即线程ID,标识唯一线程。retval: 用户定义的指针,用来存储被等待线程的返回值。
返回值 : 0代表成功。 失败,返回的则是错误号。
*/
ret = pthread_join(tid, (void **)&retval);
printf("child thread exit and return values var = %d, str = %s\n", retval->var, retval->str);
pthread_exit(NULL);
return ;
}

运行结果:

child thread exit and return values var = , str = hello xls

2、函数pthread_cancel

 /*************************************************************************
> File Name: pthread_cancel1.c
> Summary: 终止线程的函数 pthread_cancel()
> Author: xuelisheng
> Created Time: 2018年12月13日
************************************************************************/ #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h> void *tfn(void *arg)
{
while()
{
printf("thread :pid = %d, tid = %lu\n",getpid(), pthread_self());
sleep();
}
return NULL;
} int main()
{
pthread_t tid;
int ret = pthread_create(&tid, NULL, tfn, NULL);
if(ret != )
{
printf("pthread_create fail\n");
exit();
}
printf("main: pid = %d, tid = %lu\n",getpid(), pthread_self()); sleep(); /*
#include<pthread.h>
int pthread_cancel(pthread_t thread)
发送终止信号给thread线程,如果成功则返回0,否则为非0值。发送成功并不意味着thread会终止。
若是在整个程序退出时,要终止各个线程,应该在成功发送 CANCEL 指令后,使用 pthread_join 函数,等待指定的线程已经完全退出以后,再继续执行;否则,很容易产生 “段错误”。
*/
ret = pthread_cancel(tid); // 终止线程tid
if(ret != )
{
printf("pthread_cancel fail\n");
exit();
} while(); return ;
}

运行结果:

thread :pid = , tid =
main: pid = , tid =
thread :pid = , tid =
thread :pid = , tid =
thread :pid = , tid =
thread :pid = , tid =
(循环等待)

3、3种终止线程的方式:exit()、pthread_exit()、pthread_cancel

情形1:

 /*************************************************************************
> File Name: pthread_cancel2.c
> Summary: 终止线程的3种方式:exit、pthread_exit()、 pthread_cancel()
> Author: xuelisheng
> Created Time: 2018年12月13日
************************************************************************/ #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h> void *tfn1(void *arg)
{
printf("thread 1 returning\n");
return (void *); // 线程函数中,这里的return (void *)111相当于 exit(111)
} void *tfn2(void *arg)
{
printf("thread 2 exiting\n");
pthread_exit((void *));
} void *tfn3(void *arg)
{
while()
{
printf("thread 3: I'm going to die in 3 seconds ...\n");
sleep();
/*pthread_testcanel(); // 自己添加取消点*/
}
return (void *);
}
int main()
{
pthread_t tid;
void *tret = NULL; pthread_create(&tid, NULL, tfn1, NULL);
pthread_join(tid, &tret);
printf("thread 1 exit code = %d\n\n", (int)tret); pthread_create(&tid, NULL, tfn2, NULL);
pthread_join(tid, &tret);
printf("thread 2 exit code = %d\n\n", (int)tret); pthread_create(&tid, NULL, tfn3, NULL);
sleep(); // 主线程休眠3秒
pthread_cancel(tid);
pthread_join(tid, &tret); // 主线程要回收子线程3,但是子线程3之前已经被cancel,tret所以返回值-1(表示失败)
printf("thread 3 exit code = %d\n\n", (int)tret); return ;
}

运行结果:

thread  returning
thread exit code = thread exiting
thread exit code = thread : I'm going to die in 3 seconds ...
thread : I'm going to die in 3 seconds ...
thread : I'm going to die in 3 seconds ...
thread exit code = -

情形2:当pthread_cancel要终止的线程没有陷入内核的操作

 /*************************************************************************
> File Name: pthread_cancel3.c
> Summary: 终止线程的3种方式:exit、pthread_exit()、 pthread_cancel() 当pthread_cancel要终止的线程没有陷入内核的操作
> Author: xuelisheng
> Created Time: 2018年12月13日
************************************************************************/ #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h> void *tfn1(void *arg)
{
printf("thread 1 returning\n");
return (void *); // 线程函数中,这里的return (void *)111相当于 exit(111)
} void *tfn2(void *arg)
{
printf("thread 2 exiting\n");
pthread_exit((void *));
} void *tfn3(void *arg)
{
29 while(1) // 终止的线程中没有陷入内核的操作(例如系统调用等)
{
//printf("thread 3: I'm going to die in 3 seconds ...\n");
//sleep(1);
/*pthread_testcanel(); // 自己添加取消点*/
}
return (void *);
}
int main()
{
pthread_t tid;
void *tret = NULL; pthread_create(&tid, NULL, tfn1, NULL);
pthread_join(tid, &tret);
printf("thread 1 exit code = %d\n\n", (int)tret); pthread_create(&tid, NULL, tfn2, NULL);
pthread_join(tid, &tret);
printf("thread 2 exit code = %d\n\n", (int)tret); pthread_create(&tid, NULL, tfn3, NULL);
sleep(); // 主线程休眠3秒
pthread_cancel(tid);
pthread_join(tid, &tret); // 主线程要回收子线程3,但是子线程3之前已经被cancel,tret所以返回值-1(表示失败)
printf("thread 3 exit code = %d\n\n", (int)tret); return ;
}

运行结果:

thread  returning
thread exit code = thread exiting
thread exit code =
(光标在此while循环...)

情形3:解决当pthread_cancel要终止的线程没有陷入内核的操作---创建线程取消点

 /*************************************************************************
> File Name: pthread_cancel4.c
> Summary: 终止线程的3种方式:exit、pthread_exit()、 pthread_cancel() 解决当pthread_cancel要终止的线程没有陷入内核的操作
> Author: xuelisheng
> Created Time: 2018年12月13日
************************************************************************/ #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h> void *tfn1(void *arg)
{
printf("thread 1 returning\n");
return (void *); // 线程函数中,这里的return (void *)111相当于 exit(111)
} void *tfn2(void *arg)
{
printf("thread 2 exiting\n");
pthread_exit((void *));
} void *tfn3(void *arg)
{
while() // 终止的线程中没有陷入内核的操作(例如系统调用等),可以添加函数pthread_testcanel()
{
//printf("thread 3: I'm going to die in 3 seconds ...\n");
//sleep(1);
pthread_testcancel(); // 自己添加取消点
}
return (void *);
}
int main()
{
pthread_t tid;
void *tret = NULL; pthread_create(&tid, NULL, tfn1, NULL);
pthread_join(tid, &tret);
printf("thread 1 exit code = %d\n\n", (int)tret); pthread_create(&tid, NULL, tfn2, NULL);
pthread_join(tid, &tret);
printf("thread 2 exit code = %d\n\n", (int)tret); pthread_create(&tid, NULL, tfn3, NULL);
sleep(); // 主线程休眠3秒
pthread_cancel(tid);
pthread_join(tid, &tret); // 主线程要回收子线程3,但是子线程3之前已经被cancel,tret所以返回值-1(表示失败)
printf("thread 3 exit code = %d\n\n", (int)tret); return ;
}

运行结果:

thread  returning
thread exit code = thread exiting
thread exit code = thread exit code = -