C++线程同步实战

一 点睛

线程同步基本思想:同步各个线程对资源(比如全局变量、文件)的访问。如果不对资源访问进行线程同步,则会产生资源访问冲突的问题。对于多线程程序,访问冲突问题是很普遍的问题,解决方法是引入锁(互斥锁、读写锁),获得锁的线程可以完成“读——修改——写”的操作,然后释放锁给其他线程,没有获得锁的线程只能等待而不能访问共享数据,这样“读——修改——写”3步操作组成一个原子操作,要么都执行,要么都不执行,不会执行到中间被打断,也不会在其他处理器上并行做这个操作。

二 举例

一个线程正在读取一个全局变量,虽然读取全局变量的这个语句在C/C++源代码中是一条语句,但编译为机器代码后,CPU指令处理这个过程的时候,需要多条指令来处理这个读取变量的过程,如果这一系列的指令被其他一个线程打断了,也就是说CPU还没执行完全部读取变量的所有指令,而去执行另外一个线程了,另外一个线程对这个全局变量进行修改,这样修改完后又返回原来的线程,继续执行读取变量的指令,此时变量的值已经改变了,这样第一个线程的执行结果就不是预期结果。

三 多线程访问共享变量造成竞争例子

1 步骤说明

从内存单元读入寄存器

把寄存器中的值增加

把寄存器中的新值写回内存单元

2 图例

当两个线程对同一个变量做增操作时候,会出现下面情况:

 如果两个线程在串行操作下分别对i进行累加,那么i的值应该是7,但上图两个线程并行执行结果是是6.因为B线程并没有等A线程做完i+1后开始执行,而是A线程刚刚把i从内存读入寄存器后就开始执行了,所以B线程也是在i=5的时候开始执行,这样A执行结果是6,B执行的结果也是6.因此在这种没有做同步的情况下,多个线程对全局变量的进行累加,最终结果是小于或者等于它们串行操作的结果。

3 代码

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/time.h>
#include <string.h>
#include <cstdlib>
int gcn = 0;   //定义一个全局变量,用于累加

void *thread_1(void *arg) {    //第一个线程
    int j;
    for (j = 0; j < 100000000; j++) {  //开始累加
        gcn++;
    }  
    pthread_exit((void *)0);
}

void *thread_2(void *arg) {   //第二个线程
    int j;
    for (j = 0; j < 100000000; j++) {   //开始累加     
        gcn++;
    }  
    pthread_exit((void *)0);
}
int main(void)
{
    int j,err;
    pthread_t th1, th2;
     
    for (j = 0; j < 10; j++)   //做10次测试
    {
        err = pthread_create(&th1, NULL, thread_1, (void *)0);   //创建第1个线程
        if (err != 0) {
            printf("create new thread error:%s\n", strerror(err));
            exit(0);
        }  
        err = pthread_create(&th2, NULL, thread_2, (void *)0);   //创建第2个线程
        if (err != 0) {
            printf("create new thread error:%s\n", strerror(err));
            exit(0);
        }  
           
        err = pthread_join(th1, NULL);   //等待第一个线程结束
        if (err != 0) {
            printf("wait thread done error:%s\n", strerror(err));
            exit(1);
        }
        err = pthread_join(th2, NULL);   //等待第二个线程结束
        if (err != 0) {
            printf("wait thread done error:%s\n", strerror(err));
            exit(1);
        }
        printf("gcn=%d\n", gcn);
        gcn = 0;
    }
    return 0;
}

4 执行结果

[root@localhost test]# g++ -o test test.cpp -lpthread
[root@localhost test]# ./test
gcn=200000000
gcn=200000000
gcn=200000000
gcn=200000000
gcn=194321031
gcn=200000000
gcn=200000000
gcn=193992148
gcn=200000000
gcn=194882538

5 说明

从结果看到,有几次没有达到200000000,是因为累加操作编译成机器代码后,变成3个操作,3个操作无法组成原子操作,被另外一个线程打断。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 多线程实战PDF是一本介绍多线程编程实践的PDF电子书。多线程是指在一个程序中同时运行多个线程,每个线程都可以执行不同的任务。多线程可以提高程序的执行效率、响应速度和资源利用率,是现代计算机应用中常用的技术。 该电子书主要介绍了多线程编程的原理、方法和实践经验。首先,它从多线程的基本概念和原理入手,介绍了线程的创建、启动、终止和同步等基本操作。然后,它详细介绍了多线程编程中常见的问题和解决方案,如线程间的通信、资源竞争、死锁和并发性问题等。同时,它还介绍了多线程编程的一些高级技术,如线程池、信号量、互斥锁和条件变量等。 该电子书还通过实例代码和案例分析,给读者提供了一些实战经验。例如,它介绍了如何利用多线程实现文件下载、图像处理、网络爬虫和并行计算等常见应用场景。同时,它还介绍了如何利用多线程优化程序性能,如通过并行计算加速算法的运行、利用线程池提高任务处理能力等。 总之,多线程实战PDF是一本介绍多线程编程实践的电子书,它详细介绍了多线程编程的原理、方法和实践经验,并通过实例代码和案例分析给读者提供了一些实战经验。对于想要学习和应用多线程编程的人来说,这本电子书是一个很好的参考资料。 ### 回答2: 多线程是一种可以同时执行多个任务的编程技术,它可以提高程序的运行效率和响应速度。在实际应用中,我们可以利用多线程来处理一些需要同时执行的任务,例如同时下载多个文件、同时进行图像处理等。 在实现多线程的应用中,我们通常会遇到一些问题,如线程之间的数据共享、线程的同步与互斥等。为了更好地理解多线程的使用和解决这些问题,可以通过实践来加深理解。 以一个多线程实战的PDF为例,假设我们需要编写一个程序,能够同时下载多个PDF文件并保存到本地。我们可以首先定义一个下载函数,在该函数中使用多线程来实现同时下载多个PDF文件的功能。 在下载函数中,我们可以通过创建多个线程,并将每个线程分配到不同的下载任务上。通过在每个线程中实现下载逻辑,我们可以同时进行多个文件的下载,提高下载效率。 同时,为了确保线程之间的数据共享和操作的正确性,我们可以使用一些同步机制,如互斥锁(mutex)和条件变量(condition),来保证线程之间的协作和安全性。通过这些同步机制,我们可以避免多个线程同时访问和修改共享资源的问题,保证下载的正确进行。 在实际编写的过程中,我们还可以优化多线程的性能,例如合理设置线程的数量、调整下载任务的分配策略等。同时,我们也需要考虑一些问题,如线程的优雅退出、线程的异常处理等,以确保程序的健壮性。 总之,多线程实战PDF是一个相当实用和有意义的应用场景,通过实践和理论相结合的方式,我们可以更好地理解和掌握多线程的使用,提高程序的效率和可靠性。 ### 回答3: C多线程实战PDF是一本介绍多线程编程并提供实际案例的电子书籍。多线程是指在一个程序中同时执行多个线程,可以充分利用计算机资源,提高程序的运行效率。本书通过具体的项目实例,重点讲解了如何在C语言中实现多线程编程。 本书首先介绍了多线程的概念和原理,包括线程的创建、同步与互斥、线程的调度等基本知识。然后通过实战项目,让读者学会如何使用多线程解决实际问题。这些实战案例涵盖了多个领域,如网络编程、图像处理、并行计算等,旨在帮助读者理解多线程的应用场景和技巧。 在实战案例中,读者将学习如何使用多线程编写一个简单的Web服务器,实现同时处理多个HTTP请求。同时,还可以学习如何使用多线程进行图像处理,例如并行地对图像进行压缩或特效处理。此外,本书还介绍了如何使用多线程进行并行计算,以提高程序的性能。 C多线程实战PDF适合有一定C语言编程基础的读者学习。通过阅读本书,读者可以深入了解多线程编程的原理和技术,掌握多线程编程的核心概念和方法,并能灵活应用于实际项目中。无论是对于想要提升编程技能的程序员,还是对于对多线程编程感兴趣的技术爱好者,本书都是一本很好的学习资料。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值