Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 当pthread在等待互斥时死亡时会发生什么?_C_Windows_Multithreading - Fatal编程技术网

C 当pthread在等待互斥时死亡时会发生什么?

C 当pthread在等待互斥时死亡时会发生什么?,c,windows,multithreading,C,Windows,Multithreading,如果一个进程有三个线程,T1、T2和T3,并且所有三个线程都试图获取互斥体M1上的锁,我知道其中一个线程将获取互斥体,而另外两个线程将等待它们获取互斥体 如果我使用pthread_mutexattr_setrobust()使线程健壮,那么我知道如果T1持有M1,并且T1在释放之前终止,M1、T2将被唤醒,返回值为eownerded。T2然后可以清除受保护资源的状态 现在,如果T1拥有M1,而T2和T3在等待M1,会发生什么。T2被终止。会发生什么?当T1释放M1时,互斥锁是否直接转到T3?T3是

如果一个进程有三个线程,T1、T2和T3,并且所有三个线程都试图获取互斥体M1上的锁,我知道其中一个线程将获取互斥体,而另外两个线程将等待它们获取互斥体

如果我使用pthread_mutexattr_setrobust()使线程健壮,那么我知道如果T1持有M1,并且T1在释放之前终止,M1、T2将被唤醒,返回值为eownerded。T2然后可以清除受保护资源的状态

现在,如果T1拥有M1,而T2和T3在等待M1,会发生什么。T2被终止。会发生什么?当T1释放M1时,互斥锁是否直接转到T3?T3是否获得EOOWNERDEAD,或者只是在T3看来好像什么都没发生过,不需要清理?看起来T3应该只取M1,因为T2不可能让线程进入不一致的状态。有答案吗?这是一个我感兴趣的知识问题,而不是试图解决一个特定的问题,因此,如果能就这个问题提供进一步阅读的建议,我将不胜感激

编辑:我不是想弄清楚如何正确地执行它,而是想弄清楚当T2被终止或取消时(对这两种情况都感兴趣,并且只开始了解它可能对结果造成的不同),pthread实现通常会发生什么。它是被定义的行为吗


我的目标平台是使用Windows Services for Unix的Windows,以防它依赖于平台,但我的兴趣是应该发生什么

必须使用条件变量才能使其完美工作。我在下面复制粘贴了一些文档

条件变量允许线程与共享资源的值同步。通常,条件变量用作线程之间的通知系统

例如,您可以有一个计数器,一旦达到某个计数,您就希望线程被激活。计数器达到限制后激活的线程将等待条件变量。活动线程在此条件变量上发出信号,通知其他线程在此条件变量上等待/休眠;从而导致等待的线程被唤醒。如果希望向等待条件变量唤醒的所有线程发送信号,也可以使用广播机制。从概念上讲,这是由右边的图用伪代码建模的

当等待条件变量时,等待应该在循环中,而不是在简单的if语句中,因为存在虚假的唤醒。您不能保证如果某个线程被唤醒,它是信号或广播调用的结果


文档链接:

根据POSIX.1-2008tc1中
pthread\u mutex\u lock()
的规范:

  • 如果
    pthread\u mutex\u lock()
    返回零或
    [EOWNERDEAD]
    ,线程将成为互斥锁的所有者
  • 当包含所属线程(或者可选地,所属线程)的进程在拥有互斥时终止时,会发生错误
    [eownerded]
在您的示例中,
pthread\u mutex\u lock()
对T2不成功,因此T3将毫无错误地获取M1。

注意:我的回答完全基于书面标准,而不是个人经验或相关专业知识

取消pthread分为两种情况:

如果pthread被配置为延迟取消(这是默认值),那么根据标准的文本读取,在声明互斥锁(或声明互斥锁失败)之前,不会处理取消请求因为
pthread\u mutex\u lock
和friends不在可取消的函数列表中,如图所示

我不确定各种实现是否真的以这种方式运行,因为这似乎是不可取的。如果一个实现在试图声明互斥时确实允许取消(可能是因为
pthread\u mutex\u lock
函数在内部使用了列出的可取消函数之一),我希望根据Jille的回答,它会导致互斥保持一致且未声明,但该标准似乎没有明确要求

如果pthread配置为异步取消,则行为未定义:

pthread_cancel()、pthread_setcancelstate()和pthread_setcanceltype()函数被定义为异步取消安全函数

POSIX.1-2008本卷中的任何其他函数都不需要异步取消安全

如果线程启用了异步取消功能,并且在执行非异步取消安全的函数时被取消,则该行为未定义

似乎无法终止单个pthread。从

当信号传递到线程时,如果该信号的动作指定终止、停止或继续,则整个进程应分别终止、停止或继续


Windows没有pthreads,请编辑您的问题以澄清上下文。你的目标平台真的是Cygwin吗?或者您正在使用第三方库,如pthreads-win32?。。。在任何情况下,正确的答案几乎肯定是终止T2会导致未定义的行为,因为终止Windows上的线程通常会导致未定义的行为。不要这样做。如果您使用的是pthreads-win32,请注意
pthread\u kill
“仅支持零sig值,用于线程有效性检查”。健壮的互斥体只有在您拥有进程共享互斥体时才有意义,因为强制线程终止本身就是危险的。如果使用pthread_cancel(),则应在退出线程之前使用取消状态和清理处理程序修复状态并解锁互斥锁。(pthread_kill()不会终止单个线程,除非您有一个调用pthread_exit()的信号处理程序,这相当危险。)就像pthreads-win32一样