linux多线程服务端编程 mobi,Linux多线程服务端编程(一)

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

学习陈硕老师的《Linux多线程服务端编程》笔记

第1章 线程安全的对象生命期管理

编写线程安全的类是不难的,只要用同步原语保护内部状态即可。但是对象的生与死不能由对象自身拥有的mutex(互斥器)来保护。

1.1 当析构函数遇到多线程

当一个对象可能被多个线程同时看到时,那么对象的销毁时机就会变得模糊不清,可能出现多种竞态条件(race condition):在即将析构一个对象时,对象会不会在另一个线程被析构?

如何保证在执行成员函数期间,对象不会在另一个线程被析构?

在调用某个对象的成员函数之前,如何得知这个对象还活着?它的析构函数会不会碰巧执行到一半?

线程安全的class应该满足三个条件:多个线程同时访问时,其表现出正确的行为;

无论操作系统如何调度这些线程,无论这些线程的执行顺序如何交织;

调用端代码无需额外的同步或其他协调协作。

下面看这个简单的计数器类Counter:1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22class {

public:

Counter() : value_(0){}

Counter(const Counter &) = delete;

Counter & operator=(const Counter &) = delete;

int64_t value() const;

int64_t getAndIncrease();

private:

int64_t value_;

mutable std::mutex mutex_;

};

int64_t Counter::value () const {

mutex_.lock();

std::lock_guard<:mutex> lck(mutex_, std::adopt_lock);

return value_;

}

int64_t Counter::getAndIncrease() {

mutex_.lock();

std::lock_guard<:mutex> lck(mutex_, std::adopt_lock);

int64_t ret = value_++;

return ret;

}

每个Counter对象有自己的mutex_,因此不同对象不构成锁争用(lock contention)。两个线程有可能同时执行第20行,前提是它们访问的不是同一个Counter对象。

尽管Counter类本身毫无疑问是线程安全的,但如果Counter是动态创建的并通过指针来访问,则race condition仍然存在。

验证代码:1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24#include

#include

#include "Counter.h"

void display(Counter *pcounter){

if ( pcounter ) {

int64_t v = pcounter->getAndIncrease();

std::cout << v << " ";

delete pcounter;

}

}

int main(){

std::thread threads[4];

Counter *pcounter = new Counter;

for (int i = 0; i < 4; ++i) {

threads[i] = std::thread(display, pcounter);

}

for (auto &t: threads) {

t.join();

}

return 0;

}

1.2 对象的创建很简单

对象在构造的过程中,唯一的要求是在构造期间不要泄露this指针:不要在构造函数中注册任何回调;

也不要在构造函数中把this指针传给跨线程的对象;

即便在构造函数的最后一行也不行。

构造函数执行期间,对象还未完全初始化,this指针泄露给其他对象(其自身创建的子对象除外),那么别的线程有可能访问半成品对象,造成难以预料的后果。即使在最后一行也不要泄露this指针,因为有可能正在构造的对象是一个基类。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值