PTHREAD_CREATE - Linux手册页
Linux程序员手册 第3部分
更新日期: 2020-06-09
名称
pthread_create-创建一个新线程
语法
#include <pthread.h> int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
编译并链接-pthread。
说明
pthread_create()函数在调用过程中启动一个新线程。新线程通过调用start_routine()开始执行。 arg作为start_routine()的唯一参数传递。
新线程以下列方式之一终止:
- *
- 它调用pthread_exit(3),并指定退出状态值,该值对于调用pthread_join(3)的同一进程中的另一个线程可用。
- *
- 它从start_routine()返回。这等效于使用return语句中提供的值调用pthread_exit(3)。
- *
- 它被取消(请参阅pthread_cancel(3))。
- *
- 进程中的任何线程都调用exit(3),或者主线程从main()返回。这导致进程中所有线程的终止。
attr参数指向一个pthread_attr_t结构,该结构的内容在线程创建时用于确定新线程的属性。使用pthread_attr_init(3)和相关函数初始化此结构。如果attr为NULL,则使用默认属性创建线程。
返回之前,成功调用pthread_create()会将新线程的ID存储在线程指向的缓冲区中;此标识符用于在后续对其他pthreads函数的调用中引用线程。
新线程继承了创建线程的信号掩码(pthread_sigmask(3))的副本。新线程的未决信号集为空(sigpending(2))。新线程不会继承创建线程的备用信号堆栈(sigaltstack(2))。
新线程继承了调用线程的浮点环境(fenv(3))。
新线程的CPU时间时钟的初始值为0(请参阅pthread_getcpuclockid(3))。
Linux-specific details
新线程继承了调用线程的功能集(请参阅功能(7))和CPU亲和力掩码(请参阅sched_setaffinity(2))的副本。
返回值
成功时,pthread_create()返回0;否则,返回0。如果出错,则返回错误号,并且* thread的内容未定义。
错误说明
属性
有关本节中使用的术语的说明,请参见attribute(7)。
Interface | Attribute | Value |
pthread_create() | Thread safety | MT-Safe |
遵循规范
POSIX.1-2001,POSIX.1-2008。
备注
有关pthread_create()在* thread中返回的线程ID的更多信息,请参见pthread_self(3)。除非采用实时调度策略,否则在调用pthread_create()之后,将不确定接下来将执行哪个线程(调用者或新线程)。
线程可以是可连接的也可以是分离的。如果一个线程是可连接的,则另一个线程可以调用pthread_join(3)等待该线程终止并获取其退出状态。仅当终止的可连接线程已被连接时,其最后资源才释放回系统。当分离的线程终止时,其资源将自动释放回系统:不可能与线程联接以获得其退出状态。使线程分离对于某些类型的守护程序线程非常有用,这些守护程序线程的退出状态是应用程序不需要关心的。默认情况下,除非将attr设置为以分离状态创建线程(使用pthread_attr_setdetachstate(3)),否则将以可连接状态创建新线程。
在NPTL线程实现下,如果程序启动时的RLIMIT_STACK软资源限制具有" unlimited"以外的任何其他值,则它将确定新线程的默认堆栈大小。使用pthread_attr_setstacksize(3),可以在用于创建线程的attr参数中显式设置堆栈大小属性,以获取默认值以外的堆栈大小。如果RLIMIT_STACK资源限制设置为" unlimited",则每个体系结构值将用于堆栈大小。这是一些体系结构的价值:
- 体系结构默认堆栈大小 i3862兆字节 IA-6432 MB PowerPC4 MB S / 3902兆字节 Sparc-322 MB Sparc-644兆字节 x86_642 MB
BUGS
在过时的LinuxThreads实现中,一个进程中的每个线程都有一个不同的进程ID。这违反了POSIX线程规范,并且是许多其他不符合该标准的原因。参见pthreads(7)。
示例
下面的程序演示了pthread_create()的用法以及pthreads API中的许多其他功能。
在以下运行中,在提供NPTL线程实现的系统上,堆栈大小默认为"堆栈大小"资源限制所给定的值:
$ ulimit -s 8192 # The stack size limit is 8 MB (0x800000 bytes) $ ./a.out hola salut servus Thread 1: top of stack near 0xb7dd03b8; argv_string=hola Thread 2: top of stack near 0xb75cf3b8; argv_string=salut Thread 3: top of stack near 0xb6dce3b8; argv_string=servus Joined with thread 1; returned value was HOLA Joined with thread 2; returned value was SALUT Joined with thread 3; returned value was SERVUS
在下一次运行中,该程序为创建的线程显式设置1 MB的堆栈大小(使用pthread_attr_setstacksize(3)):
$ ./a.out -s 0x100000 hola salut servus Thread 1: top of stack near 0xb7d723b8; argv_string=hola Thread 2: top of stack near 0xb7c713b8; argv_string=salut Thread 3: top of stack near 0xb7b703b8; argv_string=servus Joined with thread 1; returned value was HOLA Joined with thread 2; returned value was SALUT Joined with thread 3; returned value was SERVUS
Program source
#include <pthread.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <ctype.h> #define handle_error_en(en, msg) \ do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0) #define handle_error(msg) \ do { perror(msg); exit(EXIT_FAILURE); } while (0) struct thread_info { /* Used as argument to thread_start() */ pthread_t thread_id; /* ID returned by pthread_create() */ int thread_num; /* Application-defined thread # */ char *argv_string; /* From command-line argument */ }; /* Thread start function: display address near top of our stack, and return upper-cased copy of argv_string */ static void * thread_start(void *arg) { struct thread_info *tinfo = arg; char *uargv, *p; printf("Thread %d: top of stack near %p; argv_string=%s\n", tinfo->thread_num, &p, tinfo->argv_string); uargv = strdup(tinfo->argv_string); if (uargv == NULL) handle_error("strdup"); for (p = uargv; *p != aq##代码##aq; p++) *p = toupper(*p); return uargv; } int main(int argc, char *argv[]) { int s, tnum, opt, num_threads; struct thread_info *tinfo; pthread_attr_t attr; int stack_size; void *res; /* The "-s" option specifies a stack size for our threads */ stack_size = -1; while ((opt = getopt(argc, argv, "s:")) != -1) { switch (opt) { case aqsaq: stack_size = strtoul(optarg, NULL, 0); break; default: fprintf(stderr, "Usage: %s [-s stack-size] arg...\n", argv[0]); exit(EXIT_FAILURE); } } num_threads = argc - optind; /* Initialize thread creation attributes */ s = pthread_attr_init(&attr); if (s != 0) handle_error_en(s, "pthread_attr_init"); if (stack_size > 0) { s = pthread_attr_setstacksize(&attr, stack_size); if (s != 0) handle_error_en(s, "pthread_attr_setstacksize"); } /* Allocate memory for pthread_create() arguments */ tinfo = calloc(num_threads, sizeof(struct thread_info)); if (tinfo == NULL) handle_error("calloc"); /* Create one thread for each command-line argument */ for (tnum = 0; tnum < num_threads; tnum++) { tinfo[tnum].thread_num = tnum + 1; tinfo[tnum].argv_string = argv[optind + tnum]; /* The pthread_create() call stores the thread ID into corresponding element of tinfo[] */ s = pthread_create(&tinfo[tnum].thread_id, &attr, &thread_start, &tinfo[tnum]); if (s != 0) handle_error_en(s, "pthread_create"); } /* Destroy the thread attributes object, since it is no longer needed */ s = pthread_attr_destroy(&attr); if (s != 0) handle_error_en(s, "pthread_attr_destroy"); /* Now join with each thread, and display its returned value */ for (tnum = 0; tnum < num_threads; tnum++) { s = pthread_join(tinfo[tnum].thread_id, &res); if (s != 0) handle_error_en(s, "pthread_join"); printf("Joined with thread %d; returned value was %s\n", tinfo[tnum].thread_num, (char *) res); free(res); /* Free memory allocated by thread */ } free(tinfo); exit(EXIT_SUCCESS); }
另外参见
getrlimit(2),pthread_attr_init(3),pthread_cancel(3),pthread_detach(3),pthread_equal(3),pthread_exit(3),pthread_getattr_np(3),pthread_join(3),pthread_self(3),pthread_setattr_default_np(3) pthreads(7)
出版信息
这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/。