长生栈 长生栈
首页
  • 编程语言

    • C语言
    • C++
    • Java
    • Python
  • 数据结构和算法

    • 全排列算法实现
    • 动态规划算法
  • CMake
  • gitlab 安装和配置
  • docker快速搭建wordpress
  • electron+react开发和部署
  • Electron-创建你的应用程序
  • ImgUI编译环境
  • 搭建图集网站
  • 使用PlantUml画时序图
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Living Team

编程技术分享
首页
  • 编程语言

    • C语言
    • C++
    • Java
    • Python
  • 数据结构和算法

    • 全排列算法实现
    • 动态规划算法
  • CMake
  • gitlab 安装和配置
  • docker快速搭建wordpress
  • electron+react开发和部署
  • Electron-创建你的应用程序
  • ImgUI编译环境
  • 搭建图集网站
  • 使用PlantUml画时序图
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 文件操作

  • Linux进程和线程

    • 进程创建
    • 在进程中启动程序
    • 等待进程结束
    • 线程简介
    • 多线程编程举例
    • 线程同步
      • 两个线程并发执行
        • 示例代码
        • 输出
        • 分析
      • 用信号量同步线程
        • 示例代码
        • 输出
        • 分析
    • 线程属性
  • Linux信号

  • 进程间通信

  • Socket

  • C语言
  • Linux进程和线程
DC Wang
2023-02-18
目录

线程同步

# 线程同步

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

# 输出

1
2
1
2
...

Waiting for thread to finish...
Thread joined
1
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
  • 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

# 输出

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

# 分析

  • 通过信号量,实现了两线程的同步操作。 sem_wait()和sem_post()都以原子方式工作。
  • 信号量的值可以大于1。
  • 当两个线程同时阻塞于sem_wait,如果有第三个线程执行了post操作,那么前两个线程有一个会执行,另一个仍等待,且信号量的值仍为0。
编辑 (opens new window)
#C#Linux#线程
上次更新: 2023/02/19, 10:48:02
多线程编程举例
线程属性

← 多线程编程举例 线程属性→

最近更新
01
ESP32-网络摄像头方案
06-14
02
ESP32-PWM驱动SG90舵机
06-14
03
ESP32-实时操作系统freertos
06-14
更多文章>
Theme by Vdoing | Copyright © 2019-2025 DC Wang All right reserved | 辽公网安备 21021102001125号 | 吉ICP备20001966号-2
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式