pthread_create是一个非常重要的函数,它可以在Linux操作系统中创建线程。在此文中,我会详细介绍如何使用pthread_create函数以及注意事项,帮助读者更好地使用pthread_create函数。
一、pthread_create的介绍
pthread_create函数是POSIX线程库中的一个函数,它可以在Linux操作系统中创建线程。该函数的原型如下:
#include
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
其中,第1个参数thread用于存放新创建线程的ID;第2个参数attr指向线程属性对象,如果为NULL,则使用默认属性;第3个参数start_routine是线程函数的指针;第4个参数arg是传递给线程函数的参数。线程函数的原型必须为:
void *thread_func(void *arg);
其中,arg是上面的pthread_create函数的第4个参数。
二、pthread_create的使用方法
1.基本流程
1.1 头文件及编译链接选项
为了使用pthread_create函数,必须包含头文件pthread.h。同时,由于需要链接POSIX线程库,因此需要加上链接选项-lpthread进行编译链接。示例如下:
#include
#include
int main()
{
pthread_t thread_id;
pthread_create(&thread_id, NULL, thread_func, NULL);
printf("Thread created.\n");
pthread_join(thread_id, NULL);
printf("Thread finished.\n");
return 0;
}
上面代码中,首先包含了头文件pthread.h。在编译链接时,需要加上链接选项-lpthread,即:
$ gcc -o test test.c -lpthread
1.2 创建线程
通过调用pthread_create函数来创建线程。线程创建成功后,会返回线程ID,线程函数即可运行。示例如下:
void *thread_func(void *arg)
{
printf("Thread function is running.\n");
return NULL;
}
int main()
{
pthread_t thread_id;
pthread_create(&thread_id, NULL, thread_func, NULL);
printf("Thread created.\n");
return 0;
}
注意,pthread_create函数执行成功之后,并不表示线程函数已经运行完毕。需要使用pthread_join函数来等待线程函数运行完毕才能继续往下走。
1.3 等待线程结束
使用pthread_join函数等待线程结束。示例如下:
void *thread_func(void *arg)
{
printf("Thread function is running.\n");
return NULL;
}
int main()
{
pthread_t thread_id;
pthread_create(&thread_id, NULL, thread_func, NULL);
printf("Thread created.\n");
pthread_join(thread_id, NULL);
printf("Thread finished.\n");
return 0;
}
在调用pthread_join函数时,第一个参数是线程ID,第二个参数是线程返回值,如果不关心返回值,可以传入NULL。调用pthread_join函数会阻塞当前线程,直到指定的线程运行完毕才会继续往下执行。
2.参数详解
2.1 线程ID
线程ID是用来唯一标识一个线程的变量。可以通过调用pthread_create函数创建新的线程并返回线程ID,如:
pthread_t thread_id;
pthread_create(&thread_id, NULL, thread_func, NULL);
2.2 线程属性
线程属性控制线程的行为和特性,包括线程栈的大小、调度策略、优先级等。如果不需要对线程进行特殊的设置,可以将线程属性参数设置为NULL。如果需要设置,可以使用pthread_attr_init函数来初始化线程属性变量,并使用pthread_create函数的第二个参数传递。
示例:
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&thread_id, &attr, thread_func, NULL);
2.3 线程函数
线程函数是一个普通的C函数,中文名为线程例程,用于在线程中运行。线程函数的返回值类型必须为void *,表示不需要返回值或者返回值不关心。线程函数的参数类型必须为void *,因为它能够接受任何类型的指针作为参数。调用pthread_create函数时,需要传递线程函数指针作为第三个参数。
示例:
void *thread_func(void *arg)
{
printf("Thread function is running.\n");
return NULL;
}
pthread_create(&thread_id, NULL, thread_func, NULL);
2.4 线程函数参数
线程函数的参数可以是任何类型的指针,不需要传递一个特定的类型。如果需要传递多个参数,可以将它们打包成一个结构体或者数组。调用pthread_create函数时,需要将参数作为第四个参数传递给线程函数。
示例:
void *thread_func(void *arg)
{
int a = *(int *)arg;
printf("Thread function parameter is %d.\n", a);
return NULL;
}
int main()
{
pthread_t thread_id;
int a = 10;
pthread_create(&thread_id, NULL, thread_func, &a);
printf("Thread created.\n");
pthread_join(thread_id, NULL);
printf("Thread finished.\n");
return 0;
}
三、注意事项
1.线程使用完毕后需要释放资源
需要使用pthread_join函数等待线程结束,并且对于创建的线程也需要释放资源,可以使用pthread_detach函数来分离线程,使得线程退出后可以自动释放。
示例:
void *thread_func(void *arg)
{
printf("Thread function is running.\n");
return NULL;
}
int main()
{
pthread_t thread_id;
pthread_create(&thread_id, NULL, thread_func, NULL);
printf("Thread created.\n");
pthread_detach(thread_id);
printf("Thread detached.\n");
return 0;
}
2.线程函数需要考虑线程同步和互斥问题
多个线程同时访问共享资源时,需要对共享资源进行互斥保护,否则可能会发生数据竞争问题。可以使用pthread_mutex_t来实现互斥锁,使用pthread_cond_t来实现条件变量,从而实现线程同步和互斥机制。
示例:
pthread_mutex_t mutex;
void *thread_func(void *arg)
{
pthread_mutex_lock(&mutex);
printf("Thread function is running.\n");
pthread_mutex_unlock(&mutex);
return NULL;
}
int main()
{
pthread_t thread_id;
pthread_mutex_init(&mutex, NULL);
pthread_create(&thread_id, NULL, thread_func, NULL);
pthread_mutex_lock(&mutex);
printf("Thread created.\n");
pthread_join(thread_id, NULL);
pthread_mutex_unlock(&mutex);
printf("Thread finished.\n");
pthread_mutex_destroy(&mutex);
return 0;
}
四、结论
通过上述介绍,我们可以很清晰的了解到pthread_create函数的基本使用方法和注意事项。使用pthread_create函数可以很方便地创建多线程处理任务,提高程序的效率。但要特别注意处理好竞争问题,避免数据竞争导致的问题。