线程同步
# 线程同步
Linux线程同步是一种机制,用于协调并发执行的线程之间的访问和修改共享资源,以避免数据竞争和保证程序的正确性和一致性。常用的同步机制包括互斥锁、条件变量、信号量等。
# 两个线程并发执行
# 示例代码
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
int run_now = 1;
char message[] = "Hello World";
void *thread_function(void *arg) {
int print_count2 = 0;
while (print_count2++ < 20) {
if (run_now == 2) {
printf("2\n");
run_now = 1;
} else {
sleep(1);
}
}
sleep(3);
}
int main() {
int res;
pthread_t a_thread;
void *thread_result;
int print_count1 = 0;
res = pthread_create(&a_thread, NULL, thread_function, (void *)message);
if (res != 0) {
perror("Thread creation failed");
exit(EXIT_FAILURE);
}
while (print_count1++ < 20) {
if (run_now == 1) {
printf("1\n");
run_now = 2;
} else {
sleep(1);
}
}
printf("\nWaiting for thread to finish...\n");
res = pthread_join(a_thread, &thread_result);
if (res != 0) {
perror("Thread join failed");
exit(EXIT_FAILURE);
}
printf("Thread joined\n");
exit(EXIT_SUCCESS);
}
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
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
# 输出
1
2
1
2
...
Waiting for thread to finish...
Thread joined
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# 分析
- 两线程可以并发执行。
- 两个线程都使用查询方式执行,效率较低。
- 可以考虑使用信号量和互斥量的通信方式。
# 用信号量同步线程
用于线程同步,有四个处理函数:
#include <semaphore.h>
//初始化信号量
int sem_init(sem_t *sem, int pshared, unsigned int val);
//信号量减1
int sem_wait(sem_t *sem);
//信号量加1
int sem_post(sem_t *sem);
//销毁信号量
int sem_destory(sem_t *sem);
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
- pshared:信号量类型,如为0,则为当前进程独享的信号量。
- val:信号量的初始值。
# 示例代码
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
sem_t bin_sem;
#define WORK_SIZE 1024
char work_area[WORK_SIZE];
void *thread_function(void *arg)
{
sem_wait(&bin_sem);
while(strncmp("end", work_area, 3) != 0)
{
// strlen(work_area) -1 去除'\n'
printf("You input %d characters\n", (int)(strlen(work_area) -1));
sem_wait(&bin_sem);
}
pthread_exit(NULL);
}
int main()
{
int res;
pthread_t a_thread;
void *thread_result;
res = sem_init(&bin_sem, 0, 0);
if (res != 0)
{
perror("Semaphore initialization failed");
exit(EXIT_FAILURE);
}
res = pthread_create(&a_thread, NULL, thread_function, NULL);
if (res != 0)
{
perror("Thread creation failed");
exit(EXIT_FAILURE);
}
printf("Input some text. Enter 'end' to finish\n");
while(strncmp("end", work_area, 3) != 0)
{
fgets(work_area, WORK_SIZE, stdin);
sem_post(&bin_sem);
}
printf("\nWaiting for thread to finish...\n");
res = pthread_join(a_thread, &thread_result);
if (res != 0)
{
perror("Thread join failed");
exit(EXIT_FAILURE);
}
printf("Thread joined\n");
sem_destroy(&bin_sem);
exit(EXIT_SUCCESS);
}
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
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
# 输出
Input some text. Enter 'end' to finish
abc
You input 3 characters
abcd
You input 4 characters
end
Waiting for thread to finish...
Thread joined
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
# 分析
- 通过信号量,实现了两线程的同步操作。 sem_wait()和sem_post()都以原子方式工作。
- 信号量的值可以大于1。
- 当两个线程同时阻塞于sem_wait,如果有第三个线程执行了post操作,那么前两个线程有一个会执行,另一个仍等待,且信号量的值仍为0。
编辑 (opens new window)
上次更新: 2023/02/19, 10:48:02
- 01
- Linux系统移植(五)--- 制作、烧录镜像并启动Linux02-05
- 03
- Linux系统移植(三)--- Linux kernel移植02-05