1.线程创建函数 pthread_create
函数原型:
#include <pthread.h>
int pthread_create (pthread_t *__restrict __newthread,
const pthread_attr_t *__restrict __attr,
void *(*__start_routine) (void *),
void *__restrict __arg)
函数个参数含义如下:
- __newthread : 该参数是一个指针,当线程创建成功时,用来返回创建的线程ID。
- __attr : 该参数用于指定线程的属性,NULL表示使用默认属性。
- __start_routine : 该参数是一个函数指针,指向线程创建后要调用的函数。这个被线程调用的函数也称为线程函数。
- __arg :该参数指向传递给线程函数的参数。
注意:线程创建成功时,pthread_create函数返回0,若不为0,则说明线程创建失败。
线程创建代码示例:
(1)不传递参数
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
int * thread(void *arg)
{
pthread_t newthid;
newthid = pthread_self();
printf("this is a new thread, thread ID = %u\n", (unsigned int)newthid);
return NULL;
}
int main(int argc, char **argv)
{
pthread_t thid;
printf("main thread, ID is %u\n", (unsigned int)pthread_self());
if (pthread_create(&thid, NULL, (void *)thread, NULL) != 0) {
printf("thread creation failed\n");
exit(1);
}
sleep(1); // 休眠1秒
// pthread_exit作用
// 1.显式地退出一个线程
// 2.如果主线程在其创建的子线程之前结束,使用pthread_exit,进程不会结束,
// 也意味着子线程可以继续执行;如果不使用pthread_exit,进程会结束
// 子线程会被迫终止。
// 3.该函数是在线程完成工作后无需继续存在时被调用,也意味着其后面的语句不被执行。
pthread_exit(NULL);
// 该语句位于pthread_exit后,不会被执行!
printf("main end...");
return 0;
}
编译并运行程序
baohua@node1:~$ gcc createthread.c -lpthread -o main
baohua@node1:~$ ./main
main thread, ID is 2957645568
this is a new thread, thread ID = 2949265152
(2)只有一个参数
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
void * thread(void *arg)
{
pthread_t newthid;
newthid = pthread_self();
printf("this is a new thread, thread ID = %u\n", (unsigned int)newthid);
// 获取父线程创建子线程时传递的参数
int index = *((int *)arg);
printf("the value of index is: %d\n", index);
return NULL;
}
int main(int argc, char **argv)
{
pthread_t thid;
printf("main thread, ID is %u\n", (unsigned int)pthread_self());
int index = 1;
if (pthread_create(&thid, NULL, thread, (void *)&index) != 0) {
printf("thread creation failed\n");
exit(1);
}
// pthread_exit作用
// 1.显式地退出一个线程
// 2.如果主线程在其创建的子线程之前结束,使用pthread_exit,进程不会结束,
// 也意味着子线程可以继续执行;如果不使用pthread_exit,进程会结束
// 子线程会被迫终止。
// 3.该函数是在线程完成工作后无需继续存在时被调用,也意味着其后面的语句不被执行。
pthread_exit(NULL);
// 该语句位于pthread_exit后,不会被执行!
printf("main end...");
return 0;
}
编译并运行程序
baohua@node1:~$ gcc createthread.c -lpthread -o main
baohua@node1:~$ ./main
main thread, ID is 1917601536
this is a new thread, thread ID = 1909221120
the value of index is: 1
(3)多个参数
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
struct thread_data
{
int thread_id;
char *message;
};
void *thread(void *arg)
{
pthread_t newthid;
newthid = pthread_self();
printf("this is a new thread, thread ID = %u\n", (unsigned int)newthid);
// 获取父线程创建子线程时传递的参数
struct thread_data *my_data;
my_data = (struct thread_data *)arg;
printf("Thread ID: %d\n", my_data->thread_id);
printf("Message: %s\n", my_data->message);
return NULL;
}
int main(int argc, char **argv)
{
pthread_t thid;
printf("main thread, ID is %u\n", (unsigned int)pthread_self());
// 借助结构体传参
struct thread_data td;
td.thread_id = 1;
td.message = "This is message";
if (pthread_create(&thid, NULL, thread, (void *)&td) != 0)
{
printf("thread creation failed\n");
exit(1);
}
// pthread_exit作用
// 1.显式地退出一个线程
// 2.如果主线程在其创建的子线程之前结束,使用pthread_exit,进程不会结束,
// 也意味着子线程可以继续执行;如果不使用pthread_exit,进程会结束
// 子线程会被迫终止。
// 3.该函数是在线程完成工作后无需继续存在时被调用,也意味着其后面的语句不被执行。
pthread_exit(NULL);
// 该语句位于pthread_exit后,不会被执行!
printf("main end...");
return 0;
}
编译并运行程序
baohua@node1:~$ gcc createthread.c -lpthread -o main
baohua@node1:~$ ./main
main thread, ID is 224532224
this is a new thread, thread ID = 216151808
Thread ID: 1
Message: This is message
2.线程终止
Linux下有三种方法使线程终止(不终止进程):
- 线程函数执行到尾部,或使用return从线程函数返回
- 线程可以被同一进程中的其他线程取消
- 通过pthread_exit函数使线程退出
注意:在任何线程中调用exit函数,都会终止进程,进而导致所有线程终止。
线程终止最重要的问题是释放临界资源。