Linux和windows进程同步与线程同步那些事儿(三): Linux线程同步详解示例

这篇具有很好参考价值的文章主要介绍了Linux和windows进程同步与线程同步那些事儿(三): Linux线程同步详解示例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Linux和windows进程同步与线程同步那些事儿(一)
Linux和windows进程同步与线程同步那些事儿(二): windows线程同步详解示例
Linux和windows进程同步与线程同步那些事儿(三): Linux线程同步详解示例
Linux和windows进程同步与线程同步那些事儿(四):windows 下进程同步
Linux和windows进程同步与线程同步那些事儿(五):Linux下进程同步

在Linux中,线程同步可以通过多种机制来实现,其中最常见的包括互斥锁(mutex)、条件变量(condition variable)和信号量(semaphore)。

1. 互斥锁(Mutex):

互斥锁是最常用的线程同步机制,它可以确保在同一时间只有一个线程可以访问共享资源。
在Linux中,可以使用pthread_mutex_t类型的互斥锁来实现线程同步。

代码示例:

#include <stdio.h>
#include <pthread.h>

int global_variable = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void* thread_function(void* arg) {
    for (int i = 0; i < 1000; i++) {
        // 加锁
        pthread_mutex_lock(&mutex);
        
        // 修改全局变量
        global_variable++;
        
        // 解锁
        pthread_mutex_unlock(&mutex);
    }
    
    return NULL;
}

int main() {
    pthread_t thread1, thread2;
    
    // 初始化mutex
    pthread_mutex_init(&mutex, NULL);
    
    // 创建两个线程
    pthread_create(&thread1, NULL, thread_function, NULL);
    pthread_create(&thread2, NULL, thread_function, NULL);
    
    // 等待线程结束
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    
    // 销毁mutex
    pthread_mutex_destroy(&mutex);
    
    printf("Global variable value: %d\n", global_variable);
    
    return 0;
}
 

2. 条件变量(Condition Variable):

条件变量用于线程间的通信和同步,允许线程等待某个特定条件的发生。
在Linux中,可以使用pthread_cond_t类型的条件变量来实现线程同步。

条件变量是一种同步机制,它允许线程在满足特定条件之前等待,并在条件满足时被其他线程通知。

示例代码:演示如何使用条件变量来控制多线程修改全局变量的值:

#include <stdio.h>
#include <pthread.h>

int global_var = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;


void* thread_function(void* arg)
{
    int new_value = *(int*)arg;
    
    pthread_mutex_lock(&mutex);
    
    // 等待条件满足
    while (global_var != 0)
    {
        pthread_cond_wait(&cond, &mutex);
    }
    
    // 修改全局变量的值
    global_var = new_value;
    
    printf("Thread %d has modified global_var to %d\n", pthread_self(), global_var);
    
    // 通知其他线程条件已经满足
    pthread_cond_broadcast(&cond);
    
    pthread_mutex_unlock(&mutex);
    
    return NULL;
}


int main()
{
    pthread_t thread1, thread2;
    int value1 = 123, value2 = 456;
    
    // 创建两个线程
    pthread_create(&thread1, NULL, thread_function, &value1);
    pthread_create(&thread2, NULL, thread_function, &value2);
    
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    
    printf("Final value of global_var is %d\n", global_var);
    
    return 0;
}

在上面的代码中,有两个线程分别调用thread_function函数。此函数接收一个整数参数作为新的全局变量值。线程首先获得互斥锁并进入临界区,然后使用pthread_cond_wait函数等待条件满足。只有当全局变量global_var的值为0时,线程才被允许修改这个变量的值。一旦满足这个条件,线程就会修改全局变量的值,并通过pthread_cond_broadcast函数通知其他等待这个条件的线程。最后,线程释放互斥锁并退出。

main函数中,我们创建了两个线程并等待它们完成。然后,我们打印最终的全局变量值。

通过使用条件变量,我们可以确保全局变量只能在满足特定条件时被修改,从而避免竞态条件和数据竞争的问题。

请注意,上述代码只是一个示例,用于说明如何使用条件变量来控制多线程修改全局变量的值。在实际的应用中,您可能还需要考虑其他方面,如错误处理和性能优化等。

3. 信号量(Semaphore):

信号量是一种经典的线程同步机制,它可以用于控制对共享资源的访问。
在Linux中,可以使用sem_t类型的信号量来实现线程同步。

在Linux下,我们可以使用信号量来实现对多线程修改全局变量的值的控制。信号量是一种用于进程间同步和互斥的机制,可以用来控制对共享资源的访问。

信号量可以分为二进制信号量计数信号量。二进制信号量只能取0或1,用于互斥操作。计数信号量可以取多个非负整数值,用于同步操作。

下面是一个简单的示例代码,实现了两个线程对全局变量进行自增操作的互斥控制:

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>

int global_var = 0;
sem_t sem;

void* thread_func(void* arg) {
    int i;
    for (i = 0; i < 100000; i++) {
        sem_wait(&sem); // 等待信号量,若为0则阻塞
        global_var++;
        sem_post(&sem); // 释放信号量,唤醒等待的线程
    }
    return NULL;
}

int main() {
    pthread_t thread1, thread2;

    sem_init(&sem, 0, 1); // 初始化信号量,初始值为1

    pthread_create(&thread1, NULL, thread_func, NULL);
    pthread_create(&thread2, NULL, thread_func, NULL);

    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    sem_destroy(&sem); // 销毁信号量

    printf("Global variable value: %d\n", global_var);

    return 0;
}

在上面的示例中,我们首先通过 sem_init 函数初始化了一个计数信号量 sem,初始值为1。然后创建了两个线程,并通过 pthread_create 函数将其与 thread_func 函数绑定。thread_func 函数中通过 sem_wait 函数等待信号量,当信号量的值为0时则阻塞,否则减1并继续执行。在对全局变量进行自增操作后,通过 sem_post 函数释放信号量,唤醒等待的线程。最后,通过 sem_destroy 函数销毁信号量。

运行该程序,两个线程会对全局变量 global_var 进行自增操作,由于信号量的存在,每次只能有一个线程能够修改该变量,从而实现了对全局变量访问的互斥控制。最终输出的全局变量值应为 200000。

需要注意的是,信号量的使用需要谨慎,错误的使用可能导致死锁等问题。确保在必要的时候对信号量加锁和解锁,并根据实际需求选择合适的信号量类型。


这些线程同步机制都可以通过Linux提供的pthread库来使用。在实际编程中,选择合适的线程同步机制取决于具体的应用场景和需求,以确保线程间的安全访问和协调。


拓展:
在 Linux 中编译依赖 pthread 库的程序,可以使用以下命令行表达式来编译:

gcc -o output_file source_file.c -lpthread

其中,output_file 是编译后生成的可执行文件的文件名,source_file.c 是需要编译的源代码文件的文件名。

选项 -lpthread 表示链接 pthread 库,将其加入到编译过程中。

如果源文件有多个,可以将它们一一列出来,例如:文章来源地址https://www.toymoban.com/news/detail-789076.html

gcc -o output_file source_file1.c source_file2.c -lpthread

到了这里,关于Linux和windows进程同步与线程同步那些事儿(三): Linux线程同步详解示例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 『Linux』第九讲:Linux多线程详解(三)_ 线程互斥 | 线程同步

    「前言」文章是关于Linux多线程方面的知识,上一篇是 Linux多线程详解(二),今天这篇是 Linux多线程详解(三),内容大致是线程互斥与线程同步,讲解下面开始! 「归属专栏」Linux系统编程 「主页链接」个人主页 「笔者」枫叶先生(fy) 「枫叶先生有点文青病」「每篇一句

    2024年02月02日
    浏览(73)
  • 【Linux从入门到精通】线程详解(线程与进程区别)

        本篇文章主要 对线程的概念和线程的控制进行了讲解 。其中我们再次对进程概念理解。同时 对比了进程和线程的区别 。希望本篇文章会对你有所帮助。  文章目录 一、线程概念 1、1 什么是线程 1、2 再次理解进程概念 1、3 轻量级进程 二、进程控制 2、1 创建线程 pt

    2024年02月07日
    浏览(38)
  • 【Linux】详解线程第三篇——线程同步和生产消费者模型

    本篇线程同步的内容是完全基于线程互斥来讲的,如果屏幕前的你对于线程互斥还不是很了解的话,可以看看我上一篇博客:【Linux】详解线程第二篇——用黄牛抢陈奕迅演唱会门票的例子来讲解【 线程互斥与锁 】 上篇线程互斥中重点讲了互斥锁,虽然解决了多线程并发导

    2024年02月07日
    浏览(41)
  • Linux应用程序开发:进程的一些事儿

      进程是一个动态过程,而非静态文件,它是程序的一次运行过程,当应用程序被加载到内存中运行之后它就称为了一个进程,当程序运行结束后也就意味着进程终止,这就是进程的一个生命周期。   Linux 系统下进程通常存在 6 种不同的状态,分为:就绪态、运行态、僵

    2023年04月24日
    浏览(46)
  • 进程线程知识之线程同步

    线程同步原因 互斥锁 信号量 条件变量 读写锁 1、线程同步原因 线程同步是为了 对共享资源的访问进行保护 ,目的是为了 解决数据一致性的问题 。 出现数据一致性问题本质在于进程中的多个线程对 共享资源的并发访问 (同时访问)。 为确保不会出现对共享资源的并发访

    2024年02月10日
    浏览(40)
  • 【物联网那些事儿】18 大物联网操作系统,Raspbian Pi、Ubuntu Core、Windows 10 IoT、Micropython、OpenWrt ....你用过哪几个?

    如果您查看我们周围所有连接的嵌入式系统,您会意识到物联网操作系统是确保安全、连接、互操作性、网络和存储等一系列任务的关键。 Raspbian Pi、Ubuntu Core、FreeRTOS、RIOT、Tizen、Micropython 是一些最流行的物联网设备操作系统。下面让我们看看具体他们都有什么特点。 操作

    2024年01月20日
    浏览(46)
  • 操作系统进程线程(三)—进程状态、同步互斥、锁、死锁

    原子操作的概念 原子操作就是不可中断的一个或者一系列操作。 原子操作如何实现 总线锁定 使用处理器提供的一个LOCK#信号,当一个处理器在总线上输出此信号的时候,其他处理器的请求将被阻塞住,那么该处理器可以独占内存。 缓存锁 总线锁开销比较大,因为把CPU和内

    2024年02月04日
    浏览(51)
  • 【Linux】详解进程通信中信号量的本质&&同步和互斥的概念&&临界资源和临界区的概念

             访问资源在安全的前提下,具有一定的顺序性,就叫做同步 。在多道程序系统中,由于资源有限,进程或线程之间可能产生冲突。同步机制就是为了解决这些冲突,保证进程或线程之间能够按照既定的顺序访问共享资源。同步机制有助于避免竞态条件和死锁(

    2024年04月25日
    浏览(45)
  • 操作系统-进程和线程-同步、互斥、死锁

    目录 一、同步互斥  二、互斥的实现方法 2.1软件实现 2.1.1单标志法 2.1.2双标志先检查 2.1.3双标志后检查 2.1.4Petersons算法 2.2硬件实现 2.2.1 TestAndSet指令 2.2.2 Swap指令   三、信号量机制 3.1整形变量  3.2 记录型变量  3.3用信号量实现进程互斥、同步、前驱关系 3.3.1互斥  3.3.2同步

    2024年02月08日
    浏览(52)
  • 【Windows线程开发】Windows线程同步技术

    我们在上一章节中讲解了关于Windows的线程基础,相信大家已经对线程有了基本的概念。这一章节中,我们来讲讲线程同步技术,包括加锁技术(原子锁和互斥体)和事件,信号量。 原子锁主要解决的问题是多线程在操作符方面的问题。 相关问题: 多个线程对同一个数据进行

    2024年02月04日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包