Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit a995bbb

Browse files
author
Anton Yarkov
committed
Added some work with PThreads
1 parent 015c5b2 commit a995bbb

File tree

4 files changed

+231
-0
lines changed

4 files changed

+231
-0
lines changed

‎multithreading/05 - PThreads.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include <pthread.h>
2+
3+
#include "Defs.h"
4+
5+
// Compilation:
6+
// gcc -std=gnu99 -pthread ErrorHandling.c LogF.c "05 - PThreads.c" -o pthreads
7+
8+
// Task:
9+
// Simple example of a counter working in 2 threads.
10+
11+
static long x = 0;
12+
13+
static void* thread_func(void* arg)
14+
{
15+
while (true)
16+
{
17+
printf("Thread 2, counter value %ld\n", ++x);
18+
sleep(1);
19+
}
20+
}
21+
22+
int main(void)
23+
{
24+
pthread_t tid;
25+
26+
ec_rv(pthread_create(&tid, NULL, thread_func, NULL))
27+
28+
while (x < 10)
29+
{
30+
printf("Thread 1, counter value %ld\n", ++x);
31+
sleep(2);
32+
}
33+
return EXIT_SUCCESS;
34+
35+
EC_CLEANUP_BGN
36+
return EXIT_FAILURE;
37+
EC_CLEANUP_END
38+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#include <pthread.h>
2+
3+
#include "Defs.h"
4+
5+
// Compilation:
6+
// gcc -std=gnu99 -pthread ErrorHandling.c LogF.c "06 - PThreads Joinable BAD.c" -o joinable_threads
7+
8+
// Task:
9+
// Simple example of an application working with 2 threads, where parent waits results from child.
10+
// Thread 2 stops calculation if common value already more than limit.
11+
12+
// WARNING! Code contains a problem marked with comment.
13+
14+
static long x = 0;
15+
16+
static void* thread_func(void* arg)
17+
{
18+
while (x < (long)arg)
19+
{
20+
printf("Thread 2, counter value %ld\n", ++x); // !!! WARNING!!! 2 Threads use the same variable. But increment operation is not atomic.
21+
sleep(1);
22+
}
23+
24+
return (void *)x;
25+
}
26+
27+
int main(void)
28+
{
29+
pthread_t tid;
30+
void *status;
31+
32+
assert(sizeof(long) <= sizeof(void *));
33+
ec_rv( pthread_create(&tid, NULL, thread_func, (void *)6) )
34+
35+
while (x < 10)
36+
{
37+
printf("Thread 1, counter value %ld\n", ++x); // !!! WARNING!!! 2 Threads use the same variable. But increment operation is not atomic.
38+
sleep(2);
39+
}
40+
41+
ec_rv( pthread_join(tid, &status) )
42+
printf("Return code of a Thread 2: %ld\n", (long)status);
43+
44+
return EXIT_SUCCESS;
45+
46+
EC_CLEANUP_BGN
47+
return EXIT_FAILURE;
48+
EC_CLEANUP_END
49+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#include <pthread.h>
2+
3+
#include "Defs.h"
4+
5+
// Compilation:
6+
// gcc -std=gnu99 -pthread ErrorHandling.c LogF.c "07 - PThreads Joinable with Sync.c" -o joinable_threads_synced
7+
8+
// Task:
9+
// Simple example of an application working with 2 threads, where parent waits results from child.
10+
// Thread 2 stops calculation if common value already more than limit.
11+
12+
// Access to variable is controlled with mutex.
13+
14+
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
15+
static long x = 0;
16+
17+
static void* thread_func(void* arg)
18+
{
19+
bool done;
20+
21+
while (true)
22+
{
23+
ec_rv( pthread_mutex_lock(&mtx) )
24+
done = x <= (long)arg;
25+
ec_rv( pthread_mutex_unlock(&mtx) )
26+
if (done)
27+
break;
28+
ec_rv( pthread_mutex_lock(&mtx) )
29+
printf("Thread 2, counter value %ld\n", ++x);
30+
ec_rv( pthread_mutex_unlock(&mtx) )
31+
sleep(1);
32+
}
33+
34+
return (void *)x;
35+
36+
EC_CLEANUP_BGN
37+
EC_FLUSH("thread_func")
38+
return NULL;
39+
EC_CLEANUP_END
40+
}
41+
42+
int main(void)
43+
{
44+
pthread_t tid;
45+
void *status;
46+
bool done;
47+
48+
assert(sizeof(long) <= sizeof(void *));
49+
ec_rv( pthread_create(&tid, NULL, thread_func, (void *)6) )
50+
51+
while (true)
52+
{
53+
ec_rv( pthread_mutex_lock(&mtx) )
54+
done = x >= 10;
55+
ec_rv( pthread_mutex_unlock(&mtx) )
56+
if (done)
57+
break;
58+
ec_rv( pthread_mutex_lock(&mtx) )
59+
printf("Thread 1, counter value %ld\n", ++x);
60+
ec_rv( pthread_mutex_unlock(&mtx) )
61+
sleep(2);
62+
}
63+
64+
ec_rv( pthread_join(tid, &status) )
65+
printf("Return code of a Thread 2: %ld\n", (long)status);
66+
67+
return EXIT_SUCCESS;
68+
69+
EC_CLEANUP_BGN
70+
return EXIT_FAILURE;
71+
EC_CLEANUP_END
72+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#include <pthread.h>
2+
3+
#include "Defs.h"
4+
5+
// Compilation:
6+
// gcc -std=gnu99 -pthread ErrorHandling.c LogF.c "08 - PThreads Joinable with Sync improved.c" -o joinable_threads_synced1
7+
8+
// Task:
9+
// Simple example of an application working with 2 threads, where parent waits results from child.
10+
// Thread 2 stops calculation if common value already more than limit.
11+
12+
// Access to variable is controlled with mutex, but located in the separate function.
13+
14+
static long get_and_incr_x(long incr)
15+
{
16+
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; // Must be static, because initialization function maybe not thread-safe.
17+
// And C++ may even use lazy initialization for mutex.
18+
static long x = 0;
19+
20+
// rtn and incr variables are on stack - i.e. local
21+
long rtn;
22+
23+
ec_rv( pthread_mutex_lock(&mtx) )
24+
rtn = x += incr; // Static variable - i.e. global. Needs to be protected.
25+
ec_rv( pthread_mutex_unlock(&mtx) )
26+
27+
return rtn;
28+
29+
EC_CLEANUP_BGN
30+
exit(EXIT_FAILURE);
31+
EC_CLEANUP_END
32+
}
33+
34+
static void* thread_func(void* arg)
35+
{
36+
long val = 0;
37+
while (val < (long)arg)
38+
{
39+
val = get_and_incr_x(1);
40+
printf("Thread 2, counter value %ld\n", val);
41+
sleep(1);
42+
}
43+
44+
return (void *)val;
45+
}
46+
47+
int main(void)
48+
{
49+
pthread_t tid;
50+
void *status;
51+
bool done;
52+
53+
assert(sizeof(long) <= sizeof(void *));
54+
ec_rv( pthread_create(&tid, NULL, thread_func, (void *)6) )
55+
56+
long val = 0;
57+
while (val < 10)
58+
{
59+
val = get_and_incr_x(1);
60+
printf("Thread 1, counter value %ld\n", val);
61+
sleep(2);
62+
}
63+
64+
ec_rv( pthread_join(tid, &status) )
65+
printf("Return code of a Thread 2: %ld\n", (long)status);
66+
67+
return EXIT_SUCCESS;
68+
69+
EC_CLEANUP_BGN
70+
return EXIT_FAILURE;
71+
EC_CLEANUP_END
72+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /