美文网首页
c语言实现多线程并发

c语言实现多线程并发

作者: 梁帆 | 来源:发表于2021-06-28 16:20 被阅读0次

首先,c语言的多线程并发,需要用到 pthread.h 库。

#include <pthread.h>

1、开启一个线程

下面代码是最基本的多线程实现:

主要分为三步:

1、声明一个线程变量th,类型为pthread_t;

2、使用pthread_create函数进行创建,第一个参数是线程变量的地址,第三个参数是线程执行的函数(返回值为void*);

3、pthread_join函数等待;

编译的时候要注意,涉及到多线程的时候,得在gcc参数里加上 -lpthread:

可以发现,成功输出了hello world。

2、开启两个线程

当我们开启两个线程,代码如下:

执行的任务都是打印1~499的时候可以发现:

输出的时候,两个线程是错序的。

再对代码做以下修改:

这里我们用到了pthread_create函数的第4个参数,这个参数的传入会反应到myfunc中的形参中去。最后输出的结果,我们可以清晰地看出th1和th2的线程标记和交错运行:

这里th2输出数字58的时候,th1才开始输出数字1。

3、多线程进行协同运算

我们创建一个数组,其中有5000个元素,我们想用两个线程来共同计算这5000个元素的加法和。

从两个线程的函数可以看出,一个线程计算前2500个值的加法和,另一个线程计算后2500个值的加法和。

main函数中,在pthread_join函数等待的th1和th2都结束后,输出对应的值。

编译运行后:

代码改进:

可以看到我们的代码里,th1和th2的执行函数中有大量的相似代码,所以我们最后用一个函数来复用,不难想到,需要通过传参的方式来实现代码复用。这里我们定义了一个结构体,结构体中有循环的起始标记first,终止标记last,区间内加法和result。

从上图可以看出,我们把myfunc1和myfun2整合到了myfunc中去。而在main函数中,我们创建线程的时候传入的参数正是结构体指针:

这样在myfunc函数中,我们就可以对传入的结构体参数中的元素进行利用了,将计算所得传到结构体的result中去。这样我们输出加法和,就可以得到跟上面一样的结果,但是代码会更整洁漂亮:

4、并发程序引起的共享内存问题

有如下代码。有两个进程,两个进程共享全局变量s。两个进程都执行一个计数功能的函数,直观地看过去,th1运行时s++要执行10000次,th2运行时s++也要执行10000次,似乎计算得到的最后s应该是20000。但实际上是这样的吗?

编译运行后,发现输出如下:

s并不是20000,而是12657。

原因其实很简单:

当我们执行s++,底层发生的事件其实是:内存中读取s→将s+1→将s写入到内存。这不是一个原子化操作,当两个线程交错运行的时候,很容易发生结果的丢失。因此最后的结果肯定是要小于20000的。这种情况有种专有名词,叫race condition。

为了解决这个问题,我们可以加锁

改进后的代码如下,学过操作系统会很好理解,无非就是为了保证共享内存区(临界区)的原子化操作,我们可以在进这段代码之前加锁(pthread_mutex_lock),意味着其他线程看到这段内存被其他人占有的时候,就不去抢占,等这段内存被解锁(pthread_mutex_unlock)之后,它才有读写这段临界区的权利。

但其实这种方式的执行速度并不快,比如这段代码里,每个线程都要进行10000次加解锁的操作,它能解决内存读写冲突的问题,但是却牺牲了效率。

相关文章

  • c语言实现多线程并发

    首先,c语言的多线程并发,需要用到 pthread.h 库。 #include 1、开启一个线程 下面代码是最基本...

  • 09|Java线程(上):Java线程的生命周期

    在Java 领域,实现并发程序的主要手段就是多线程,线程是操作系统里的一个概念,虽然各种语言如 Java、C# 等...

  • 【线程的另一种形式】

    今天研究的问题: 1. Go并发忧于Java并发? 2. Go语言的并发是多线程实现的么? 3. Java并...

  • 异步编程之事件循环机制

    JavaScript 是一门单线程语言,我们可以通过异步编程的方式来实现实现类似于多线程语言的并发操作。 本文着重...

  • iOS多线程随笔

    1. 多线程的并发控制 1.1 在CGD中快速实现多线程的并发控制 NSOperationQueue来处理并发控制...

  • Java基础(六)

    多线程 Java多线程并发 1.1 JAVA 并发知识库 1.2 JAVA 线程实现/创建方式 1.2.1 继承 ...

  • 学习总结-GDC

    多线程(GCD) 一.实现方式 pthread: C语言实现,不常用 nsthred: 基本上也不用 gcd: 常...

  • 多线程编程

    参考:C++ 并发编程 线程 windsows多线程 new thread(...) linux 多线程: pth...

  • C++标准库读书笔记: Concurrency

    由于多核的出现,使用多线程能够显著提高性能。C++11之前,C++并没有对并发提供语言层面的支持,C++标准库也没...

  • iOS多线程

    多线程 iOS中的多线程创建方式可以分为四类实现方式: pthread基于C语言,基本不使用。 NSThread基...

网友评论

      本文标题:c语言实现多线程并发

      本文链接:https://www.haomeiwen.com/subject/fxpqultx.html