首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么wait()函数(系统调用)从不返回(进行无限等待)

wait()函数是一个系统调用,用于使进程进入等待状态,直到它的子进程结束。当子进程结束时,父进程会收到一个信号,从而可以继续执行。然而,有时候wait()函数可能会出现从不返回的情况,即进行无限等待的现象。

这种情况通常是由于以下几个原因导致的:

  1. 子进程未正确退出:如果子进程没有正确退出,而是出现了异常或者陷入了死循环,那么父进程调用wait()函数时就会一直等待子进程结束,从而导致无限等待。
  2. 子进程被其他信号中断:在某些情况下,子进程可能被其他信号中断,例如被SIGSTOP或SIGCONT信号暂停或恢复执行。这样一来,父进程调用wait()函数时就会一直等待子进程结束,导致无限等待。
  3. 父进程没有正确处理信号:如果父进程没有正确处理子进程结束时的信号,例如没有注册相应的信号处理函数或者信号处理函数中没有正确处理wait()函数的返回值,那么父进程调用wait()函数时可能会出现无限等待的情况。

针对这种情况,可以采取以下措施来解决:

  1. 检查子进程的退出状态:在父进程中,可以通过wait()函数的返回值来获取子进程的退出状态,如果返回-1,则表示出现错误,可以通过errno来获取具体的错误信息。如果返回值大于0,则表示子进程的进程ID,可以通过WIFEXITED和WEXITSTATUS宏来获取子进程的退出状态。
  2. 注册信号处理函数:在父进程中,可以注册相应的信号处理函数来处理子进程结束时的信号,例如使用signal()函数注册SIGCHLD信号的处理函数。在信号处理函数中,可以调用wait()函数来获取子进程的退出状态,并进行相应的处理。
  3. 使用非阻塞方式调用wait()函数:可以使用非阻塞方式调用waitpid()函数,设置WNOHANG选项,这样即使子进程还没有结束,waitpid()函数也会立即返回,从而避免无限等待的情况。

总结起来,wait()函数从不返回(进行无限等待)的原因可能是子进程未正确退出、子进程被其他信号中断或者父进程没有正确处理信号。为了解决这个问题,可以检查子进程的退出状态、注册信号处理函数或者使用非阻塞方式调用wait()函数。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Akka 指南 之「术语及概念」

另一方面,当执行的任务可以真正同时进行时,就会出现并行。 异步 vs. 同步 如果调用者在方法返回值或引发异常之前无法取得进展,则认为方法调用是同步的。...一般来说,最好使用异步 API,因为它们保证系统能够进行。Actor 本质上是异步的:Actor 可以在消息发送之后进行其他任务,而不必等待实际的传递发生。 非阻塞 vs....如果一个线程无限期地占用资源(例如意外运行无限循环),则等待该资源的其他线程将无法进行。相反,非阻塞意味着没有线程能够无限期地延迟其他线程。...等待自由(Wait-freedom) 如果保证每个调用都以有限的步骤完成,则方法是无等待wait-free)的。如果一个方法是有界“无等待”的,那么步骤的数量有一个有限的上限。...根据这个定义,无等待方法永远不会被阻塞,因此不会发生死锁。此外,由于每个参与者都可以在有限的步骤之后(调用完成时)继续进行,因此无等待方法没有饥饿。

80160

Windows APC机制 & 可警告alertable的线程等待状态

同时,用户APC函数极为特别,它只有在线程处于“可警告alertable的线程等待状态”时才能被线程调用。但是,线程一旦开始调用APC函数,就会一次性将所有APC队列上的函数全部执行完毕。...APC函数一般不会去干扰(中断)线程的运行,从上文中知道,一个线程附带着两个APC队列(用户APC、系统APC),也就相当于这两个队列的APC函数都是由“线程本身”来储备调用的(APC函数就相当于奥运会比赛上的预备选手...如果该值为INFINITE值,则表示无限等待下去; bAlertable:函数返回方式。如果为FALSE,除非该函数调用超时,否则该函数返回。在此期间如果IO完成了回调,完成例程也不会被执行。...如果为TRUE,当该函数调用超时或者IO完成回调时,该函数都会返回——当调用超时时,该函数返回WAIT_OBJECT_0(亦即0);如果返回IO完成回调才返回的话,则返回值为WAIT_IO_COMPLETION...否则,如果所有APC函数都执行完毕了线程才真正跑起来,这时候进入SleepEx无限等待中,而没有APC例程去触发它。线程将会卡死在SleepEx处。

1.4K20
  • (67) 线程的基本协作机制 (上) 计算机程序的思维逻辑

    集合点:类似于学校或公司组团旅游,在旅游过程中有若干集合点,比如出发集合点,每个人从不同地方来到集合点,所有人到齐后进行下一项活动,在一些程序,比如并行迭代计算中,每个线程负责一部分计算,然后在集合点等待其他线程完成...一个不带时间参数,表示无限等待,实际就是调用wait(0)。...,该线程加入对象锁等待队列,线程状态变为BLOCKED,只有在获得锁后才会从wait调用返回。...线程从wait调用返回后,不代表其等待的条件就一定成立了,它需要重新检查其等待的条件,一般的调用模式是: synchronized (obj) { while (条件不成立)...代码块执行完后,等待的线程才会从wait调用返回

    66260

    Handler另类难点三问

    系统为什么提供Handler 这点大家应该都知道一些,就是为了切换线程,主要就是为了解决在子线程无法访问UI的问题。 那么为什么系统不允许在子线程中访问UI呢?...所以,我们的系统就设计出了ThreadLocal这种工具类。...具体就是会调用到nativePollOnce方法里,最终调用到epoll_wait()进行阻塞等待。 这时,主线程会进行休眠状态,也就不会消耗CPU资源。...先说说文件描述符和I/O多路复用: “在Linux操作系统中,可以将一切都看作是文件,而文件描述符简称fd,当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符,可以理解为一个索引值...通过epoll_wait方法等待I/O事件,如果当前没有可用的事件则阻塞调用线程。 拜拜 今天就说这么多了,感兴趣的朋友也可以继续深究下去,比如epoll为什么是性能最好的I/O多路复用方法?

    41510

    ThreadStatus(线程的几种状态)

    2.运行(RUNNABLE):调用start()方法,RUNNABLE包括了操作系统线程状态中的Running和Ready,也就是处于此状态的线程有可能正在执行,也有可能正在等待着CPU为它分配执行时间...(该线程已经获取了除CPU资源外的其他资源,等待获取CPU 资源后才会真正处于运行状态) 官方为什么不将这两种状态分开呢?...以下方法会让线程陷入无限期的等待状态: 1.没有设置Timeout参数的Object.wait()方法。 2.没有设置Timeout参数的Thread.join()方法。...2.1.1.2 join方法的介绍 join方法在内部使用wait()方法进行等待,底层用wait()来实现,可以释放锁。...join()与synchronized的区别是:join在内部调用wait()方法进行等待,而synchronized关键字使用的是"对象监视器"原理作为同步。

    92220

    Java并发—Java线程

    :服务器CPU资源有限,如果每个人都显示手动创建线程,不知道哪里的代码出现了多线程,在运行的时候所有线程都在抢占资源,不好控制 频繁创建,开销大 不好管理:可能无限制新建线程,可能占用过多系统资源导致死机或...notify(),nitofyAll()时需要对调用对象加锁(必须在同步代码块内) 当前线程调用某个加锁对象的wait()后,会进入该对象的monitor对象的等待队列中,释放锁,释放CPU资源,状态变为...WAITING 当前线程调用某个加锁对象的notify()或nitifyAll(),等待队列中的线程从等待队列中移动到同步队列中,线程状态由WAITING变为BLOKING 等待队列中的线程要想从wait...()中返回,除了需要有其他线程调用notify()外,还需要等待线程释放锁,获得对象的锁后才能从wait()返回 [14] join() 注意,wait()是Object的,join()是Thread...的 join()中底层调用wait() 若调用了thread2.join() 就是让当前线程进入thread2的monitor对象的等待队列中,知道thread2结束才会被唤醒 由于底层调用的是

    2K21

    Mutex的lock(), tryLock()区别

    lock函数和tryLock函数都是用于锁定对象,但他们之间有一定的区别: lock函数是阻塞的,因为它调用WaitForSingleObject函数时传递的第二个参数是INFINITE,表示无限等待下去...tryLock函数时非阻塞的,调用后立即返回。因为它调用WaitForSingleObject函数时传递的第二个参数是0,表示不等待,立即返回。...如果该内核对象处于已通知状态,则该函数立即返回WAIT_OBJECT_0。...第二个参数指明了需要等待的时间(毫秒),可以传递INFINITE指明要无限等待下去, 如果第二个参数为0,那么函数就测试同步对象的状态并立即返回。...如果等待超时,该函数返回WAIT_TIMEOUT。 如果该函数失败,返回WAIT_FAILED。

    87430

    java并发编程(十二)待续......

    然后我们在主线程中等待一段时间后中断线程,最后再调用 isInterrupted 方法来检查线程是否被中断。47、为什么 wait和notify 方法要在同步块中调用?...由于 wait 和 notify 方法需要访问到 lock 对象的监视器锁,因此只有在同步块中才能保证只有一个线程能够获得该锁,从而避免了竞态条件的发生48、为什么你应该在循环中检查等待条件?...如果不检查等待条件,可能会出现以下情况:死锁:两个或多个线程相互等待对方释放锁,导致整个系统无法正常运行。...67、为什么线程通信的方法 wait(), notify()和notifyAll()被定义在 Object 类里?...68、为什么 wait(), notify()和 notifyAll ()必须在同步方法或者同步块中被调用?69、为什么 Thread 类的 sleep()和 yield ()方法是静态的?

    58220

    从linux源码看socket(tcp)的timeout

    connectTimeout 在讨论connectTimeout之前,让我们先看下java和C语言对于socket connect调用函数签名: java: // 函数调用中携带有超时时间 public...vm_wait)); } 在write等待的时候,如果出现socket被shutdown或者socket出现错误的时候,则会跳出wait进而返回错误。...如果内核层面ack正常返回而且对端窗口不为0,仅仅应用层不返回任何数据,那么就会无限等待,直到对端有数据或者socket close/shutdown为止,如下图所示: ?...无限,SO_RCVTIMEO) Java系统调用 tcp_retries2 对端无响应 对端内核响应正常 5 min(SO_TIMEOUT,(25.6s-51.2s)根据动态rto定 SO_TIMEOUT...如果socket是阻塞的,那么将会在当前或者下一次write/read系统调用的时候返回给应用层相应的错误。

    4.7K20

    从linux源码看socket(tcp)的timeout

    connectTimeout 在讨论connectTimeout之前,让我们先看下java和C语言对于socket connect调用函数签名: java: // 函数调用中携带有超时时间 public...vm_wait)); } 在write等待的时候,如果出现socket被shutdown或者socket出现错误的时候,则会跳出wait进而返回错误。...timeout事件的触发时机如下图所示: 如果内核层面ack正常返回而且对端窗口不为0,仅仅应用层不返回任何数据,那么就会无限等待,直到对端有数据或者socket close/shutdown为止...无限,SO_RCVTIMEO) Java系统调用 tcp_retries2 对端无响应 对端内核响应正常 5 min(SO_TIMEOUT,(25.6s-51.2s)根据动态rto定 SO_TIMEOUT...如果socket是阻塞的,那么将会在当前或者下一次write/read系统调用的时候返回给应用层相应的错误。

    2K20

    2024年java面试准备--多线程篇(1)

    阻塞的情况分三种: (1)、等待阻塞:运行的线程执行wait方法,该线程会释放占用的所有资源,JVM会把该线程放入"等待池"中。...wait 方法意味着永久等待,直到被中断或被唤醒才能恢复,不会主动恢复,sleep 方法中会定义一个时间,时间到期后会主动恢复。...进程和线程区别 1.根本区别:进程是操作系统进行资源分配的最小单元,线程是操作系统进行运算调度的最小单元。 2.从属关系不同:进程中包含了线程,线程属于进程。...总结:使用Thread类的start方法不仅仅启动多线程的执行代码,还要从不同操作系统中分配资源。...3.提高线程的可管理性 线程是稀缺资源,不可能无限的创建,使用线程池可以进行统一分配、调优和监控。 4.提供更多更强大的功能 线程池具备可拓展性,允许开发人员向其中增加更多的功能。

    19520

    一次 Netty 不健壮导致的无限重连分析

    (备注:本文 Netty 版本是上古时代的 3.7.0.Final) 上篇文章见:一次 Netty 代码不健壮导致的大量 CLOSE_WAIT 连接原因分析 现象描述 开发的同学反馈 dubbo 客户端无法调用远程的服务...strace -f -T -p 238289 -o strace-new.238289.out 在 strace 中找 connect 相关的调用,根据线程号过滤对应的日志,可以看到发生了哪些系统调用...: 一开始就创建一个 socket,将该套接字设置为非阻塞,随后调用 connect 发起建立,因为是非阻塞套接字,connect 这里不阻塞直接返回 -1,随后开始等待 3s,如果 3s 内没有能建立成功...\n"); // 关闭 socket close(sockfd); return 0; } 目前的思路大概就清楚了:没有人调用epoll相关的函数去注册事件,导致内核收到SYN+ACK包以后,没有程序感兴趣去处理...现在可以推断出 RegisterTask 的 run 没有被调用。 继续看taskqueue是如何消费的,就知道 run 为什么没有被执行了。

    92430

    【Linux】探索进程控制奥秘,解锁高效实战技巧

    然后任何一方想要进行写入的时候,这个时候操作系统就会介入,将权限改回来可读可写,所以当我们的子进程进行写入的时候就会报错缺页中断。操作系统就会介入,这样就写时拷贝就可以按需进行!...父进程通过进程等待的方式,回收子进程资源,获取子进程退出信息 3.2wait()和waitpid()函数 wait pid_t wait(int* status); 功能: 等待任意一个子进程结束...返回值: 调用成功,返回收集到的子进程的PID,同时获取到了子进程的退出状态码;调用失败,返回-1,并设置错误码以指示错误的原因;如果为非阻塞等待,waitpid调用成功且没有收集到已结束的子进程,则返回...如果调用出错则返回-1 所以exec函数只有出错的返回值而没有成功的返回值。 命名理解 这些函数原型看起来很容易混,但只要掌握了规律就很好记。...我们不一定要让一个进程直接进行替换,可以创建子进程,让子进程进行替换,让父进程等待我们的结果就可以. 4.4替换为什么没有影响父进程?

    4910

    超强图文|并发编程【等待通知机制】就是这个feel~

    人工无限申请浪费口舌, 程序无限申请浪费CPU。...聪明的人就想到了 等待/通知 机制 等待/通知机制 无限循环实在太浪费CPU,而理想情况应该是这样: 柜员A如果拿不到所有账本,就傲娇的不再继续问了(线程阻塞自己 wait) 柜员B归还了柜员A需要的账本之后就主动通知柜员...因为被唤醒的线程再次获取到锁之后是从原来的 wait 之后开始执行的,wait在循环里面,所以会再次进入循环条件重新进行条件判断。...notify() 函数 随机唤醒一个:一个线程调用共享对象的 notify() 方法,会唤醒一个在该共享变量上调用 wait() 方法后被挂起的线程,一个共享变量上可能有多个线程在等待,具体唤醒那一个...,是随机的 notifyAll() 函数 唤醒所有: 与notify() 不同,notifyAll() 会唤醒在该共享变量上由于调用wait() 方法而被挂起的所有线程 看个非常简单的程序例子吧 示例程序一

    50210

    Redis 事件驱动分析

    等待客户端连接状态变化 当我们通过调用 aeCreateEventLoop() 函数把客户端连接添加到事件驱动库进行监听后,需要调用 aeMain() 函数等待客户端连接状态发生变化,其原型如下: void...aeApiPoll() 函数主要通过调用 epoll_wait() 系统调用等待被监听的客户端连接的状态发生变化,epoll_wait() 系统调用会将就绪的客户端连接保存到 events 参数中,并且通过返回值告知其数量...aeMain() 函数 aeMain() 函数用于等待客户端连接的状态发生变化,并且调用客户端连接的事件回调函数进行处理。...如果发生的是读事件,那么就调用读事件回调函数对客户端连接进行处理。如果发生的是写事件,那么就调用写事件回调函数对客户端连接进行处理。...总结 这篇文章主要介绍了 Redis 的事件驱动库的使用与原理实现,Redis的事件驱动库主要使用了 多路复用I/O 来对客户端连接进行监听,如果客户端连接从不可用变为就绪,那么事件驱动库就会调用事件相关的回调函数对连接进行处理

    1.4K20

    稳了!Java并发编程71道面试题及答案

    调用 new Thread()创建的线程缺乏管理,被称为野线程,而且可以无限制的创建,线程之间的相互竞争会导致过多占用系统资源而导致系统瘫痪,还有线程之间的频繁交替也会消耗很多系统资源。...调用 new Thread()创建的线程缺乏管理,被称为野线程,而且可以无限制的创建,线程之间的相互竞争会导致过多占用系统资源而导致系统瘫痪,还有线程之间的频繁交替也会消耗很多系统资源。...处于阻塞态的线程会不断请求资源,一旦请求成功,就会进入就绪队列,等待执行。PS:锁、IO、Socket等都资源。 等待态: 当前线程中调用wait、join、park函数时,当前线程就会进入等待态。...还有一个原因是为了避免wait和notify之间产生竞态条件。 47、为什么你应该在循环中检查等待条件?...66、为什么wait()、notify()和notifyAll ()必须在同步方法或者同步块中被调用

    42420

    Java 并发编程 71 道面试题及答案

    调用 new Thread()创建的线程缺乏管理,被称为野线程,而且可以无限制的创建,线程之间的相互竞争会导致过多占用系统资源而导致系统瘫痪,还有线程之间的频繁交替也会消耗很多系统资源。...调用 new Thread()创建的线程缺乏管理,被称为野线程,而且可以无限制的创建,线程之间的相互竞争会导致过多占用系统资源而导致系统瘫痪,还有线程之间的频繁交替也会消耗很多系统资源。...处于阻塞态的线程会不断请求资源,一旦请求成功,就会进入就绪队列,等待执行。PS:锁、IO、Socket等都资源。 等待态: 当前线程中调用wait、join、park函数时,当前线程就会进入等待态。...还有一个原因是为了避免wait和notify之间产生竞态条件。 47、为什么你应该在循环中检查等待条件?...66、为什么wait()、notify()和notifyAll ()必须在同步方法或者同步块中被调用

    49332

    Java 面试宝典!并发编程 71 道题及答案全送上!

    调用 new Thread()创建的线程缺乏管理,被称为野线程,而且可以无限制的创建,线程之间的相互竞争会导致过多占用系统资源而导致系统瘫痪,还有线程之间的频繁交替也会消耗很多系统资源。...调用 new Thread()创建的线程缺乏管理,被称为野线程,而且可以无限制的创建,线程之间的相互竞争会导致过多占用系统资源而导致系统瘫痪,还有线程之间的频繁交替也会消耗很多系统资源。...处于阻塞态的线程会不断请求资源,一旦请求成功,就会进入就绪队列,等待执行。PS:锁、IO、Socket等都资源。 等待态: 当前线程中调用wait、join、park函数时,当前线程就会进入等待态。...还有一个原因是为了避免wait和notify之间产生竞态条件。 47、为什么你应该在循环中检查等待条件?...66、为什么wait()、notify()和notifyAll ()必须在同步方法或者同步块中被调用

    42820

    Java 学习笔记(11)——多线程

    我们在call函数返回值,通过 FutureTask 对象的get方法来获取返回值 public class ThreadTask extends Thread{ @Override...而Java中将线程状态进行了进一步的细分,根据阻塞原因将阻塞状态又分为:等待(调用等待函数主动让出CPU执行权), 阻塞(线程的时间片到达,操作系统进行线程切换) 它们之间的状态如下: ?...等待唤醒 入上图所示,可以使用wait/sleep方法让线程处于等待状态。在另一个线程中使用wait线程对象的notify方法可以唤醒wait线程。...void wait() ;调用函数,使线程无限等待,直到有另外的线程将其唤醒 void wait(long timeout);调用函数,使线程进行等待,直到另外有线程将其唤醒或者等待时间已过 void...上面说过这些方法都是在 Object 类中实现的,也就是说所有的对象都可以调用。上面的等待监视器就是随意一个调用wait 的对象。这个对象会阻塞它所在的线程。

    42040
    领券