APUE course source code
guowenxue
2 days ago 01c119252bae1e252aa9e6bdba99f1b2ee756624
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
/*********************************************************************************
 *      Copyright:  (C) 2025 LingYun IoT System Studio
 *                  All rights reserved.
 *
 *       Filename:  thread.c
 *    Description:  This file is thread example program
 *
 *        Version:  1.0.0(11/04/2025)
 *         Author:  Guo Wenxue <guowenxue@gmail.com>
 *      ChangeLog:  1, Release initial version on "11/04/2025 02:26:44 PM"
 *
 ********************************************************************************/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
 
typedef struct worker_ctx_s
{
    int              shared_var;
    pthread_mutex_t  lock1; /* lock for thread1 */
    pthread_mutex_t  lock2; /* lock for thread2 */
} worker_ctx_t;
 
void *thread_worker1(void *args);
void *thread_worker2(void *args);
 
int main(int argc, char **argv)
{
    pthread_t        tid;
    pthread_attr_t   thread_attr;
    worker_ctx_t     worker_ctx;
 
    /* initial worker_ctx and lock  */
    worker_ctx.shared_var = 1000;
    pthread_mutex_init(&worker_ctx.lock1, NULL);
    pthread_mutex_init(&worker_ctx.lock2, NULL);
 
    /* lock thread2, let threa1 run first */
    pthread_mutex_lock(&worker_ctx.lock2);
 
    if( pthread_attr_init(&thread_attr) )
    {
        printf("pthread_attr_init() failure: %s\n", strerror(errno));
        return -1;
    }
 
    if( pthread_attr_setstacksize(&thread_attr, 120*1024) )
    {
        printf("pthread_attr_setstacksize() failure: %s\n", strerror(errno));
        return -1;
    }
 
    if( pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED) )
    {
        printf("pthread_attr_setdetachstate() failure: %s\n", strerror(errno));
        return -1;
    }
 
    pthread_create(&tid, &thread_attr, thread_worker1, &worker_ctx);
    printf("Thread worker1 tid[%ld] created ok\n", tid);
 
    pthread_create(&tid, NULL, thread_worker2, &worker_ctx);
    printf("Thread worker2 tid[%ld] created ok\n", tid);
 
    pthread_attr_destroy(&thread_attr);
 
    printf("Main/Control thread shared_var: %d\n", worker_ctx.shared_var);
 
    /* Wait until thread worker2 exit() */
    pthread_join(tid, NULL);
 
    while(1)
    {
        sleep(10);
    }
 
    /* destroy mutex lock */
    pthread_mutex_destroy(&worker_ctx.lock1);
    pthread_mutex_destroy(&worker_ctx.lock2);
    return 0;
}
 
void *thread_worker1(void *args)
{
    worker_ctx_t   *ctx = (worker_ctx_t *)args;
 
    if( !args )
    {
        printf("%s() get invalid arguments\n", __FUNCTION__);
        pthread_exit(NULL);
    }
 
    printf("Thread1 [%ld] start running...\n", pthread_self());
 
    while(1)
    {
        /* wait for thread1 lock */
        pthread_mutex_lock(&ctx->lock1);
 
        printf("+++: Thread1 before seelp shared_var: %d\n", ctx->shared_var);
        ctx->shared_var ++;
        sleep(2);
        printf("+++: Thread1 after  seelp shared_var: %d\n", ctx->shared_var);
 
        /* release thread2 lock */
        pthread_mutex_unlock(&ctx->lock2);
    }
 
    printf("Thread1 exit...\n");
    return NULL;
}
 
void *thread_worker2(void *args)
{
    worker_ctx_t   *ctx = (worker_ctx_t *)args;
 
    if( !args )
    {
        printf("%s() get invalid arguments\n", __FUNCTION__);
        pthread_exit(NULL);
    }
 
    printf("Thread2 [%ld] start running...\n", pthread_self());
 
    while(1)
    {
        /* wait for thread2 lock */
        if(0 != pthread_mutex_trylock(&ctx->lock2) )
        {
            continue; /* lock is busy */
        }
 
        printf("---: Thread2 before seelp shared_var: %d\n", ctx->shared_var);
        ctx->shared_var ++;
        sleep(2);
        printf("---: Thread2 after  seelp shared_var: %d\n", ctx->shared_var);
 
        /* release thread1 lock */
        pthread_mutex_unlock(&ctx->lock1);
    }
 
    printf("Thread2 exit...\n");
    return NULL;
}