Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Doc: signal.sig(timed)wait do not work outside the main thread #73560

Open
petr-motejlek mannequin opened this issue Jan 25, 2017 · 2 comments
Open

Doc: signal.sig(timed)wait do not work outside the main thread #73560

petr-motejlek mannequin opened this issue Jan 25, 2017 · 2 comments
Labels
3.11 only security fixes docs Documentation in the Doc dir type-feature A feature request or enhancement

Comments

@petr-motejlek
Copy link
Mannequin

petr-motejlek mannequin commented Jan 25, 2017

BPO 29374
Nosy @vadmium, @petr-motejlek

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = None
created_at = <Date 2017-01-25.17:25:31.331>
labels = ['3.11', 'type-feature', 'docs']
title = 'Doc: signal.sig(timed)wait do not work outside the main thread'
updated_at = <Date 2021-10-22.10:01:01.554>
user = 'https://github.com/petr-motejlek'

bugs.python.org fields:

activity = <Date 2021-10-22.10:01:01.554>
actor = 'iritkatriel'
assignee = 'docs@python'
closed = False
closed_date = None
closer = None
components = ['Documentation']
creation = <Date 2017-01-25.17:25:31.331>
creator = 'petr@motejlek.net'
dependencies = []
files = []
hgrepos = []
issue_num = 29374
keywords = []
message_count = 2.0
messages = ['286269', '286284']
nosy_count = 3.0
nosy_names = ['docs@python', 'martin.panter', 'petr@motejlek.net']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'enhancement'
url = 'https://bugs.python.org/issue29374'
versions = ['Python 3.11']

@petr-motejlek
Copy link
Mannequin Author

petr-motejlek mannequin commented Jan 25, 2017

Hi,

The documentation for signal.signal() clearly states that it is only supposed to be called on MainThread

However, it does not say so for the signal.sigwait() and neither signal.sigtimedwait()

I think this is an error on the documentation side of things (unless I misread it). When either signal.sigwait or signal.sigtimedwait are called outside MainThread, they simply never catch any signals (signal.sigwait blocks indefinitely)

I did not test this on Windows, but on both Linux and OS X the behavior is the same

Consider the below simple code

  import signal
  import os
  def sigwait():
    print("Send me a signal, my PID is {p}".format(p=os.getpid()))  
    print("Got the signal: {i}".format(i=signal.sigwait((signal.SIGUSR1,))))

If sigwait() is called on MainThread and the process receives SIGUSR1, "Got the signal: ..." gets printed. However, calling sigwait in a different thread blocks the thread indefinitely. The behavior is the same with signal.sigtimedwait() as well

@petr-motejlek petr-motejlek mannequin added type-bug An unexpected behavior, bug, or error 3.7 (EOL) end of life labels Jan 25, 2017
@petr-motejlek petr-motejlek mannequin added the docs Documentation in the Doc dir label Jan 25, 2017
@vadmium
Copy link
Member

vadmium commented Jan 25, 2017

This works for me on Linux:

>>> signal.pthread_sigmask(signal.SIG_BLOCK, {signal.SIGUSR1})
set()
>>> import threading
>>> t = threading.Thread(target=sigwait)
>>> t.start()
Send me a signal, my PID is 24197
>>> os.kill(os.getpid(), signal.SIGUSR1)
Got the signal: 10
>>> t.join()

Posix <http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigwait.html\> only defines sigwait() if the signals are already blocked. Two reasons behind this come to mind:

  1. There would be a race where the signal handler may be called first (or the signal may be ignored) at the OS level, and the sigwait() function will miss the signal and block.

  2. If the signal is handled in the context of another thread that isn’t using sigwait(), it may be consumed (handled or ignored) in the context of the other thread, with no effect on your sigwait() call.

This detail of blocking the signal seems to be a common error, so maybe the Python documentation could help point it out. (bpo-25868 comes to mind; there is a test case that IMO should block a signal before waiting for it.)

@terryjreedy terryjreedy changed the title Doc bug: signal.sigwait and signal.sigtimedwait do not work outside the Main thread Doc: signal.sig(timed)wait do not work outside the main thread Jan 27, 2017
@iritkatriel iritkatriel added 3.11 only security fixes type-feature A feature request or enhancement and removed 3.7 (EOL) end of life type-bug An unexpected behavior, bug, or error labels Oct 22, 2021
@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.11 only security fixes docs Documentation in the Doc dir type-feature A feature request or enhancement
Projects
Status: No status
Development

No branches or pull requests

2 participants