多线程vs多进程,谁在Linux能更好发挥多核CP

多线程vs多进程,谁在Linux能更好发挥多核CP,第1张

线程和多进程应该是各有所长吧,它们都能很好的发挥处理器多核性能,对于多进程来说,Linux的进程是轻量级的,进程本身的资源开销相当小,而且Linux的进程可以互相协作、互相发送消息、互相中断,还可以共享内存段,编写多个相互协作的进程也要比编写多线程更容易,所以在Linux编程中多进程要比多线程更加常用一些。但是多进程之间共享变量不是很容易,它们毕竟是各自独立的实体,而多线程可以很容易的共享变量(当然前提是搞好线程同步),所以会有一些数据库服务器程序用多线程技术,总之就是各有所长,根据编程的需要进行取舍。

在Linux系统中使用C/C++进行多线程编程时,我们遇到最多的就是对同一变量的多线程读写问题,大多情况下遇到这类问题都是通过锁机制来处理,但这对程序的性能带来了很大的影响,当然对于那些系统原生支持原子 *** 作的数据类型来说,我们可以使用原子 *** 作来处理,这能对程序的性能会得到一定的提高。那么对于那些系统不支持原子 *** 作的自定义数据类型,在不使用锁的情况下如何做到线程安全呢?本文将从线程局部存储方面,简单讲解处理这一类线程安全问题的方法。

一、数据类型

在C/C++程序中常存在全局变量、函数内定义的静态变量以及局部变量,对于局部变量来说,其不存在线程安全问题,因此不在本文讨论的范围之内。全局变量和函数内定义的静态变量,是同一进程中各个线程都可以访问的共享变量,因此它们存在多线程读写问题。在一个线程中修改了变量中的内容,其他线程都能感知并且能读取已更改过的内容,这对数据交换来说是非常快捷的,但是由于多线程的存在,对于同一个变量可能存在两个或两个以上的线程同时修改变量所在的内存内容,同时又存在多个线程在变量在修改的时去读取该内存值,如果没有使用相应的同步机制来保护该内存的话,那么所读取到的数据将是不可预知的,甚至可能导致程序崩溃。

如果需要在一个线程内部的各个函数调用都能访问、但其它线程不能访问的变量,这就需要新的机制来实现,我们称之为Static memory local to a thread (线程局部静态变量),同时也可称之为线程特有数据(TSD: Thread-Specific Data)或者线程局部存储(TLS: Thread-Local Storage)。这一类型的数据,在程序中每个线程都会分别维护一份变量的副本(copy),并且长期存在于该线程中,对此类变量的 *** 作不影响其他线程。如下图:

二、一次性初始化

在讲解线程特有数据之前,先让我们来了解一下一次性初始化。多线程程序有时有这样的需求:不管创建多少个线程,有些数据的初始化只能发生一次。列如:在C++程序中某个类在整个进程的生命周期内只能存在一个实例对象,在多线程的情况下,为了能让该对象能够安全的初始化,一次性初始化机制就显得尤为重要了。——在设计模式中这种实现常常被称之为单例模式(Singleton)。Linux中提供了如下函数来实现一次性初始化:

#include <pthread.h>

// Returns 0 on success, or a positive error number on error

int pthread_once (pthread_once_t *once_control, void (*init) (void))

利用参数once_control的状态,函数pthread_once()可以确保无论有多少个线程调用多少次该函数,也只会执行一次由init所指向的由调用者定义的函数。init所指向的函数没有任何参数,形式如下:

void init (void)

{

// some variables initializtion in here

}

另外,参数once_control必须是pthread_once_t类型变量的指针,指向初始化为PTHRAD_ONCE_INIT的静态变量。在C++0x以后提供了类似功能的函数std::call_once (),用法与该函数类似。使用


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/sjk/9894770.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-03
下一篇2023-05-03

发表评论

登录后才能评论

评论列表(0条)

    保存