1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
|
'\" t
.\" Copyright (c) 2008 Linux Foundation, written by Michael Kerrisk
.\" <mtk.manpages@gmail.com>
.\"
.\" SPDX-License-Identifier: Linux-man-pages-copyleft
.\"
.TH pthread_attr_init 3 2023-07-20 "Linux man-pages 6.05.01"
.SH NAME
pthread_attr_init, pthread_attr_destroy \- initialize and destroy
thread attributes object
.SH LIBRARY
POSIX threads library
.RI ( libpthread ", " \-lpthread )
.SH SYNOPSIS
.nf
.B #include <pthread.h>
.PP
.BI "int pthread_attr_init(pthread_attr_t *" attr );
.BI "int pthread_attr_destroy(pthread_attr_t *" attr );
.fi
.SH DESCRIPTION
The
.BR pthread_attr_init ()
function initializes the thread attributes object pointed to by
.I attr
with default attribute values.
After this call, individual attributes of the object can be set
using various related functions (listed under SEE ALSO),
and then the object can be used in one or more
.BR pthread_create (3)
calls that create threads.
.PP
Calling
.BR pthread_attr_init ()
on a thread attributes object that has already been initialized
results in undefined behavior.
.PP
When a thread attributes object is no longer required,
it should be destroyed using the
.BR pthread_attr_destroy ()
function.
Destroying a thread attributes object has no effect
on threads that were created using that object.
.PP
Once a thread attributes object has been destroyed,
it can be reinitialized using
.BR pthread_attr_init ().
Any other use of a destroyed thread attributes object
has undefined results.
.SH RETURN VALUE
On success, these functions return 0;
on error, they return a nonzero error number.
.SH ERRORS
POSIX.1 documents an
.B ENOMEM
error for
.BR pthread_attr_init ();
on Linux these functions always succeed
(but portable and future-proof applications should nevertheless
handle a possible error return).
.SH ATTRIBUTES
For an explanation of the terms used in this section, see
.BR attributes (7).
.TS
allbox;
lbx lb lb
l l l.
Interface Attribute Value
T{
.na
.nh
.BR pthread_attr_init (),
.BR pthread_attr_destroy ()
T} Thread safety MT-Safe
.TE
.sp 1
.SH STANDARDS
POSIX.1-2008.
.SH HISTORY
POSIX.1-2001.
.SH NOTES
The
.I pthread_attr_t
type should be treated as opaque:
any access to the object other than via pthreads functions
is nonportable and produces undefined results.
.SH EXAMPLES
The program below optionally makes use of
.BR pthread_attr_init ()
and various related functions to initialize a thread attributes
object that is used to create a single thread.
Once created, the thread uses the
.BR pthread_getattr_np (3)
function (a nonstandard GNU extension) to retrieve the thread's
attributes, and then displays those attributes.
.PP
If the program is run with no command-line argument,
then it passes NULL as the
.I attr
argument of
.BR pthread_create (3),
so that the thread is created with default attributes.
Running the program on Linux/x86-32 with the NPTL threading implementation,
we see the following:
.PP
.in +4n
.EX
.\" Results from glibc 2.8, SUSE 11.0; Oct 2008
.RB "$" " ulimit \-s" " # No stack limit ==> default stack size is 2 MB"
unlimited
.RB "$" " ./a.out"
Thread attributes:
Detach state = PTHREAD_CREATE_JOINABLE
Scope = PTHREAD_SCOPE_SYSTEM
Inherit scheduler = PTHREAD_INHERIT_SCHED
Scheduling policy = SCHED_OTHER
Scheduling priority = 0
Guard size = 4096 bytes
Stack address = 0x40196000
Stack size = 0x201000 bytes
.EE
.in
.PP
When we supply a stack size as a command-line argument,
the program initializes a thread attributes object,
sets various attributes in that object,
and passes a pointer to the object in the call to
.BR pthread_create (3).
Running the program on Linux/x86-32 with the NPTL threading implementation,
we see the following:
.PP
.in +4n
.EX
.\" Results from glibc 2.8, SUSE 11.0; Oct 2008
.RB "$" " ./a.out 0x3000000"
posix_memalign() allocated at 0x40197000
Thread attributes:
Detach state = PTHREAD_CREATE_DETACHED
Scope = PTHREAD_SCOPE_SYSTEM
Inherit scheduler = PTHREAD_EXPLICIT_SCHED
Scheduling policy = SCHED_OTHER
Scheduling priority = 0
Guard size = 0 bytes
Stack address = 0x40197000
Stack size = 0x3000000 bytes
.EE
.in
.SS Program source
\&
.\" SRC BEGIN (pthread_attr_init.c)
.EX
#define _GNU_SOURCE /* To get pthread_getattr_np() declaration */
#include <err.h>
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
\&
static void
display_pthread_attr(pthread_attr_t *attr, char *prefix)
{
int s, i;
size_t v;
void *stkaddr;
struct sched_param sp;
\&
s = pthread_attr_getdetachstate(attr, &i);
if (s != 0)
errc(EXIT_FAILURE, s, "pthread_attr_getdetachstate");
printf("%sDetach state = %s\en", prefix,
(i == PTHREAD_CREATE_DETACHED) ? "PTHREAD_CREATE_DETACHED" :
(i == PTHREAD_CREATE_JOINABLE) ? "PTHREAD_CREATE_JOINABLE" :
"???");
\&
s = pthread_attr_getscope(attr, &i);
if (s != 0)
errc(EXIT_FAILURE, s, "pthread_attr_getscope");
printf("%sScope = %s\en", prefix,
(i == PTHREAD_SCOPE_SYSTEM) ? "PTHREAD_SCOPE_SYSTEM" :
(i == PTHREAD_SCOPE_PROCESS) ? "PTHREAD_SCOPE_PROCESS" :
"???");
\&
s = pthread_attr_getinheritsched(attr, &i);
if (s != 0)
errc(EXIT_FAILURE, s, "pthread_attr_getinheritsched");
printf("%sInherit scheduler = %s\en", prefix,
(i == PTHREAD_INHERIT_SCHED) ? "PTHREAD_INHERIT_SCHED" :
(i == PTHREAD_EXPLICIT_SCHED) ? "PTHREAD_EXPLICIT_SCHED" :
"???");
\&
s = pthread_attr_getschedpolicy(attr, &i);
if (s != 0)
errc(EXIT_FAILURE, s, "pthread_attr_getschedpolicy");
printf("%sScheduling policy = %s\en", prefix,
(i == SCHED_OTHER) ? "SCHED_OTHER" :
(i == SCHED_FIFO) ? "SCHED_FIFO" :
(i == SCHED_RR) ? "SCHED_RR" :
"???");
\&
s = pthread_attr_getschedparam(attr, &sp);
if (s != 0)
errc(EXIT_FAILURE, s, "pthread_attr_getschedparam");
printf("%sScheduling priority = %d\en", prefix, sp.sched_priority);
\&
s = pthread_attr_getguardsize(attr, &v);
if (s != 0)
errc(EXIT_FAILURE, s, "pthread_attr_getguardsize");
printf("%sGuard size = %zu bytes\en", prefix, v);
\&
s = pthread_attr_getstack(attr, &stkaddr, &v);
if (s != 0)
errc(EXIT_FAILURE, s, "pthread_attr_getstack");
printf("%sStack address = %p\en", prefix, stkaddr);
printf("%sStack size = %#zx bytes\en", prefix, v);
}
\&
static void *
thread_start(void *arg)
{
int s;
pthread_attr_t gattr;
\&
/* pthread_getattr_np() is a non\-standard GNU extension that
retrieves the attributes of the thread specified in its
first argument. */
\&
s = pthread_getattr_np(pthread_self(), &gattr);
if (s != 0)
errc(EXIT_FAILURE, s, "pthread_getattr_np");
\&
printf("Thread attributes:\en");
display_pthread_attr(&gattr, "\et");
\&
exit(EXIT_SUCCESS); /* Terminate all threads */
}
\&
int
main(int argc, char *argv[])
{
pthread_t thr;
pthread_attr_t attr;
pthread_attr_t *attrp; /* NULL or &attr */
int s;
\&
attrp = NULL;
\&
/* If a command\-line argument was supplied, use it to set the
stack\-size attribute and set a few other thread attributes,
and set attrp pointing to thread attributes object. */
\&
if (argc > 1) {
size_t stack_size;
void *sp;
\&
attrp = &attr;
\&
s = pthread_attr_init(&attr);
if (s != 0)
errc(EXIT_FAILURE, s, "pthread_attr_init");
\&
s = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if (s != 0)
errc(EXIT_FAILURE, s, "pthread_attr_setdetachstate");
\&
s = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
if (s != 0)
errc(EXIT_FAILURE, s, "pthread_attr_setinheritsched");
\&
stack_size = strtoul(argv[1], NULL, 0);
\&
s = posix_memalign(&sp, sysconf(_SC_PAGESIZE), stack_size);
if (s != 0)
errc(EXIT_FAILURE, s, "posix_memalign");
\&
printf("posix_memalign() allocated at %p\en", sp);
\&
s = pthread_attr_setstack(&attr, sp, stack_size);
if (s != 0)
errc(EXIT_FAILURE, s, "pthread_attr_setstack");
}
\&
s = pthread_create(&thr, attrp, &thread_start, NULL);
if (s != 0)
errc(EXIT_FAILURE, s, "pthread_create");
\&
if (attrp != NULL) {
s = pthread_attr_destroy(attrp);
if (s != 0)
errc(EXIT_FAILURE, s, "pthread_attr_destroy");
}
\&
pause(); /* Terminates when other thread calls exit() */
}
.EE
.\" SRC END
.SH SEE ALSO
.ad l
.nh
.BR pthread_attr_setaffinity_np (3),
.BR pthread_attr_setdetachstate (3),
.BR pthread_attr_setguardsize (3),
.BR pthread_attr_setinheritsched (3),
.BR pthread_attr_setschedparam (3),
.BR pthread_attr_setschedpolicy (3),
.BR pthread_attr_setscope (3),
.BR pthread_attr_setsigmask_np (3),
.BR pthread_attr_setstack (3),
.BR pthread_attr_setstackaddr (3),
.BR pthread_attr_setstacksize (3),
.BR pthread_create (3),
.BR pthread_getattr_np (3),
.BR pthread_setattr_default_np (3),
.BR pthreads (7)
|