关于线程安全的两种极端情况……

lucifer886 2015-07-17 09:17:26
一、函数的参数传递
线程1调用

func(Pointer *A)
{
mutex.lock();
A->...
mutex.unlock();
}

线程2调用

{
mutex.lock();
delete A;
A = NULL;
mutex.unlock();
}

有没有可能出现一种情况,线程1刚进入函数时(形参A被赋值)后,程序被切换到线程2,A被delete之后再次切回到线程1,导致程序崩溃;

二、函数的返回值
这种情况应该是会出现的……
线程1:

Pointer* __stdcall pointerA()
{
locker(&mutex);
return A;
}

Pointer *A = ponterA();
A->...


线程2:

{
mutex.lock();
delete A;
A = NULL;
mutex.unlock();
}

当线程1:Pointer *A = ponterA()这一行返回时,程序被切换到线程2然后A被delete掉,再回到线程1的时候程序崩溃;

...全文
138 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2015-07-17
  • 打赏
  • 举报
回复
《Windows核心编程》
jiqiang01234 2015-07-17
  • 打赏
  • 举报
回复
一个对象如果在不同的线程创建和释放,是非常危险的。楼主的例子确实可能出现崩溃。 不要把代码建立在这种非常难以判断原子性的基础上。 如果必须在多线程中创建和释放对象。建议用智能指针weak_ptr<>,因为它会强制用户在获得可操作的指针前判断指针是否为空(当然,依然需要同步保护)
king191923157 2015-07-17
  • 打赏
  • 举报
回复
mutex是全局变量的话可能有用吧
lucifer886 2015-07-17
  • 打赏
  • 举报
回复
引用 1 楼 king191923157 的回复:
没仔细看,但楼主既然是参数传递,线程2的A=NULL;没有传到外面,线程一不能通过A==NULL来判断是否为无效内存
线程2的A和线程1的形参A都指向同一片内存,只是想知道函数调用(参数构造)到函数内第一行被调用是不是原子的。虽然看起来显而易见不是的……
lucifer886 2015-07-17
  • 打赏
  • 举报
回复
引用 2 楼 hlx_beat 的回复:
func(Pointer *A) { mutex.lock(); A->... mutex.unlock(); } 有鸟用? 你这有保护作用?
别这么暴躁,少打一行
func(Pointer *A)
{
      mutex.lock();
      if (A != NULL)
            A->...
      mutex.unlock();
}
不过想了下这个A跟外面那个A就不是一个东西……看来这么写根本是有问题的。
hlx_beat 2015-07-17
  • 打赏
  • 举报
回复
func(Pointer *A) { mutex.lock(); A->... mutex.unlock(); } 有鸟用? 你这有保护作用?
king191923157 2015-07-17
  • 打赏
  • 举报
回复
没仔细看,但楼主既然是参数传递,线程2的A=NULL;没有传到外面,线程一不能通过A==NULL来判断是否为无效内存
feiyunw 2015-07-17
  • 打赏
  • 举报
回复
楼主,确实有可能出现你设想的情况。 这是读写锁问题,读写操作无法并发。
fly_dragon_fly 2015-07-17
  • 打赏
  • 举报
回复
线程上锁是为了保护同一个变量, 两个线程操作的A已经不是同一变量了.
Qlaiaqu 2015-07-17
  • 打赏
  • 举报
回复
线程1调用 func(Pointer *A) { mutex.lock(); if(A) A->... mutex.unlock(); } 线程2调用 { mutex.lock(); delete A; A = NULL; mutex.unlock(); } 有没有可能出现一种情况,线程1刚进入函数时(形参A被赋值)后,程序被切换到线程2,A被delete之后再次切回到线程1,导致程序崩溃。 有可能,进入func之后,在没有获取锁之前,A状态不定,有可能被删除也有可能没被删除,只有当线程1真正获取了锁,A的状态才确定。这时候需要通过合法判断A来使用A。 二、函数的返回值 这种情况应该是会出现的…… 线程1: C/C++ code ? 1 2 3 4 5 6 7 8 Pointer* __stdcall pointerA() { locker(&mutex); return A; } Pointer *A = ponterA(); A->... 线程2: { mutex.lock(); delete A; A = NULL; mutex.unlock(); } 当线程1:Pointer *A = ponterA()这一行返回时,程序被切换到线程2然后A被delete掉,再回到线程1的时候程序崩溃; 使用函数返回值返回需要锁保护的指针是不安全的,函数返回后,A本身已经没有被锁保护了,那么无法确定A什么时候会被线程2删除。 这里线程安全的含义是,任何需要使用A的地方,否则只有出现不可确定性,崩溃是迟早的事情

64,685

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧