1
|
#include
<pthread.h> |
1. 第一個例子
1
|
int pthread_create(pthread_t
* thread , const pthread_attr_t
*attr, void *(*start_routine)( void *) void *arg); |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
#include
<stdio.h> #include
<pthread.h> void * thread ( void *arg
) { printf ( "This
is a thread and arg = %d.\n" ,
*( int *)arg); *( int *)arg
= 0; return arg; } int main( int argc, char *argv[]
) { pthread_t
th; int ret; int arg
= 10; int *thread_ret
= NULL; ret
= pthread_create( &th, NULL, thread ,
&arg ); if (
ret != 0 ){ printf ( "Create
thread error!\n" ); return -1; } printf ( "This
is the main process.\n" ); pthread_join(
th, ( void **)&thread_ret
); printf ( "thread_ret
= %d.\n" ,
*thread_ret ); return 0; } |
2. 線程的合併與分離
3. 線程的屬性
1
2
|
int pthread_attr_init(pthread_attr_t
*attr); int pthread_attr_destory(pthread_attr_t
*attr); |
3.1 綁定屬性
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#include
<stdio.h> #include
<pthread.h> …… int main( int argc, char *argv[]
) { pthread_attr_t
attr; pthread_t
th; …… pthread_attr_init(
&attr ); pthread_attr_setscope(
&attr, PTHREAD_SCOPE_SYSTEM ); pthread_create(
&th, &attr, thread ,
NULL ); …… } |
3.2 分離屬性
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#include
<stdio.h> #include
<pthread.h> …… int main( int argc, char *argv[]
) { pthread_attr_t
attr; pthread_t
th; …… pthread_attr_init(
&attr ); pthread_attr_setscope(
&attr, PTHREAD_SCOPE_SYSTEM ); pthread_create(
&th, &attr, thread ,
NULL ); …… } |
3.3 調度屬性
1
2
3
4
|
struct sched_param
{ int sched_priority; } int pthread_attr_setschedparam(pthread_attr_t
*attr, struct sched_param
*param); |
1
|
int pthread_attr_setinheritsched(pthread_attr_t
*attr, int inheritsched); |
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
|
#include
<stdio.h> #include
<pthread.h> …… int main( int argc, char *argv[]
) { pthread_attr_t
attr; pthread_t
th; …… pthread_attr_init(
&attr ); pthread_attr_setscope(
&attr, PTHREAD_SCOPE_SYSTEM ); pthread_create(
&th, &attr, thread ,
NULL ); …… } #include
<stdio.h> #include
<unistd.h> #include
<stdlib.h> #include
<pthread.h> #define
THREAD_COUNT 12 void show_thread_policy( int threadno
) { int policy; struct sched_param
param; pthread_getschedparam(
pthread_self(), &policy, ¶m ); switch (
policy ){ case SCHED_OTHER: printf ( "SCHED_OTHER
%d\n" ,
threadno ); break ; case SCHED_RR: printf ( "SCHDE_RR
%d\n" ,
threadno ); break ; case SCHED_FIFO: printf ( "SCHED_FIFO
%d\n" ,
threadno ); break ; default : printf ( "UNKNOWN\n" ); } } void * thread ( void *arg
) { int i,
j; long threadno
= ( long )arg; printf ( "thread
%d start\n" ,
threadno ); sleep(1); show_thread_policy(
threadno ); for (
i = 0; i < 10; ++i ) { for (
j = 0; j < 100000000; ++j ){} printf ( "thread
%d\n" ,
threadno ); } printf ( "thread
%d exit\n" ,
threadno ); return NULL; } int main( int argc, char *argv[]
) { long i; pthread_attr_t
attr[THREAD_COUNT]; pthread_t
pth[THREAD_COUNT]; struct sched_param
param; for (
i = 0; i < THREAD_COUNT; ++i ) pthread_attr_init(
&attr[i] ); for (
i = 0; i < THREAD_COUNT / 2; ++i ) { param.sched_priority
= 10; pthread_attr_setschedpolicy(
&attr[i], SCHED_FIFO ); pthread_attr_setschedparam(
&attr[i], ¶m ); pthread_attr_setinheritsched(
&attr[i], PTHREAD_EXPLICIT_SCHED ); } for (
i = THREAD_COUNT / 2; i < THREAD_COUNT; ++i ) { param.sched_priority
= 20; pthread_attr_setschedpolicy(
&attr[i], SCHED_FIFO ); pthread_attr_setschedparam(
&attr[i], ¶m ); pthread_attr_setinheritsched(
&attr[i], PTHREAD_EXPLICIT_SCHED ); } for (
i = 0; i < THREAD_COUNT; ++i ) pthread_create(
&pth[i], &attr[i], thread ,
( void *)i
); for (
i = 0; i < THREAD_COUNT; ++i ) pthread_join(
pth[i], NULL ); for (
i = 0; i < THREAD_COUNT; ++i ) pthread_attr_destroy(
&attr[i] ); return 0; } |
3.4 堆棧大小屬性
1
|
int pthread_attr_setstacksize(pthread_attr_t
*attr, size_t stacksize); |
3.5 滿棧警戒區屬性
1
|
int pthread_attr_setguardsize(pthread_attr_t
*attr, size_t guardsize); |
4. 線程本地存儲
1
2
3
4
|
int pthread_key_create(pthread_key_t
*key, void (*destructor)( void *)); int pthread_key_delete(pthread_key_t
key); void *
pthread_getspecific(pthread_key_t key); int pthread_setspecific(pthread_key_t
key, const void *value); |
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
|
#include
<stdio.h> #include
<stdlib.h> #include
<pthread.h> #define
THREAD_COUNT 10 pthread_key_t
g_key; typedef struct thread_data{ int thread_no; }
thread_data_t; void show_thread_data() { thread_data_t
*data = pthread_getspecific( g_key ); printf ( "Thread
%d \n" ,
data->thread_no ); } void * thread ( void *arg
) { thread_data_t
*data = (thread_data_t *)arg; printf ( "Start
thread %d\n" ,
data->thread_no ); pthread_setspecific(
g_key, data ); show_thread_data(); printf ( "Thread
%d exit\n" ,
data->thread_no ); } void free_thread_data( void *arg
) { thread_data_t
*data = (thread_data_t*)arg; printf ( "Free
thread %d data\n" ,
data->thread_no ); free (
data ); } int main( int argc, char *argv[]
) { int i; pthread_t
pth[THREAD_COUNT]; thread_data_t
*data = NULL; pthread_key_create(
&g_key, free_thread_data ); for (
i = 0; i < THREAD_COUNT; ++i ) { data
= malloc ( sizeof (
thread_data_t ) ); data->thread_no
= i; pthread_create(
&pth[i], NULL, thread ,
data ); } for (
i = 0; i < THREAD_COUNT; ++i ) pthread_join(
pth[i], NULL ); pthread_key_delete(
g_key ); return 0; } |
5. 線程的同步
5.1 互斥鎖
1
2
3
4
5
|
int pthread_mutex_init(pthread_mutex_t
*restrict mutex, const pthread_mutexattr_t
*restrict attr); int pthread_mutex_destory(pthread_mutex_t
*mutex ); int pthread_mutex_lock(pthread_mutex_t
*mutex); int pthread_mutex_trylock(pthread_mutex_t
*mutex); int pthread_mutex_unlock(pthread_mutex_t
*mutex); |
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
|
#include
<stdio.h> #include
<stdlib.h> #include
<errno.h> #include
<unistd.h> #include
<pthread.h> pthread_mutex_t
g_mutex; int g_lock_var
= 0; void *
thread1( void *arg
) { int i,
ret; time_t end_time; end_time
= time (NULL)
+ 10; while ( time (NULL)
< end_time ) { ret
= pthread_mutex_trylock( &g_mutex ); if (
EBUSY == ret ) { printf ( "thread1:
the varible is locked by thread2.\n" ); } else { printf ( "thread1:
lock the variable!\n" ); ++g_lock_var; pthread_mutex_unlock(
&g_mutex ); } sleep(1); } return NULL; } void *
thread2( void *arg
) { int i; time_t end_time; end_time
= time (NULL)
+ 10; while ( time (NULL)
< end_time ) { pthread_mutex_lock(
&g_mutex ); printf ( "thread2:
lock the variable!\n" ); ++g_lock_var; sleep(1); pthread_mutex_unlock(
&g_mutex ); } return NULL; } int main( int argc, char *argv[]
) { int i; pthread_t
pth1,pth2; pthread_mutex_init(
&g_mutex, NULL ); pthread_create(
&pth1, NULL, thread1, NULL ); pthread_create(
&pth2, NULL, thread2, NULL ); pthread_join(
pth1, NULL ); pthread_join(
pth2, NULL ); pthread_mutex_destroy(
&g_mutex ); printf ( "g_lock_var
= %d\n" ,
g_lock_var ); return 0; } |
5.2 條件變量
1
2
3
4
5
6
|
int pthread_cond_init(pthread_cond_t
*cond, const pthread_condattr_t
*attr); int pthread_cond_destory(pthread_cond_t
*cond); int pthread_cond_wait(pthread_cond_t
*cond, pthread_mutex_t *mutex); int pthread_cond_timedwait(pthread_cond_t
*cond,pthread_mutex_t *mutex, const timespec
*abstime); int pthread_cond_signal(pthread_cond_t
*cond); int pthread_cond_broadcast(pthread_cond_t
*cond); |
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
|
#include
<stdio.h> #include
<stdlib.h> #include
<pthread.h> #define
BUFFER_SIZE 5 pthread_mutex_t
g_mutex; pthread_cond_t
g_cond; typedef struct { char buf[BUFFER_SIZE]; int count; }
buffer_t; buffer_t
g_share = { "" ,
0}; char g_ch
= 'A' ; void *
producer( void *arg
) { printf ( "Producer
starting.\n" ); while (
g_ch != 'Z' )
{ pthread_mutex_lock(
&g_mutex ); if (
g_share.count < BUFFER_SIZE ) { g_share.buf[g_share.count++]
= g_ch++; printf ( "Prodcuer
got char[%c]\n" ,
g_ch - 1 ); if (
BUFFER_SIZE == g_share.count ) { printf ( "Producer
signaling full.\n" ); pthread_cond_signal(
&g_cond ); } } pthread_mutex_unlock(
&g_mutex ); } printf ( "Producer
exit.\n" ); return NULL; } void *
consumer( void *arg
) { int i; printf ( "Consumer
starting.\n" ); while (
g_ch != 'Z' )
{ pthread_mutex_lock(
&g_mutex ); printf ( "Consumer
waiting\n" ); pthread_cond_wait(
&g_cond, &g_mutex ); printf ( "Consumer
writing buffer\n" ); for (
i = 0; g_share.buf[i] && g_share.count; ++i ) { putchar (
g_share.buf[i] ); --g_share.count; } putchar ( '\n' ); pthread_mutex_unlock(
&g_mutex ); } printf ( "Consumer
exit.\n" ); return NULL; } int main( int argc, char *argv[]
) { pthread_t
ppth, cpth; pthread_mutex_init(
&g_mutex, NULL ); pthread_cond_init(
&g_cond, NULL ); pthread_create(
&cpth, NULL, consumer, NULL ); pthread_create(
&ppth, NULL, producer, NULL ); pthread_join(
ppth, NULL ); pthread_join(
cpth, NULL ); pthread_mutex_destroy(
&g_mutex ); pthread_cond_destroy(
&g_cond ); return 0; } |