473,545 Members | 1,977 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

exit, signals and exceptions

Hi. I posted this question to comp.lang.c++, but am rephrasing it a bit
from what I learned and posting to comp.lang.c++.m oderated for more insight.

So how do I solve my problem? I want it so that when the user presses
Ctrl-C or eds the task from task manager (or the kill command in UNIX) then
the system should shutdown gracefully. This means it should call the
destructors of all objects, which means freeing dynamic memory, closing
sockets, closing file handles, close SQL connections, etc.

My approach was to set up a signal handler using std::signal. If the signal
handler does nothing the program resumes execution at the point where the
signal was raised (kind of like the RESUME command in basic).

So one of my thoughts was to throw an exception in the signal handler, and
after returning control to the point in the function where the signal was
raised, the program would detect the exception and perform stack unwinding.
But we are not allowed to throw exceptions in signal functions. On my
compiler, Borland C++ 6 I get the message: << Project.exe faulted with
message "applicatio n-defined exception". Process Stopped. Use Step or Run to
continue. >>

My other thought was to call std::exit in the signal handler. But
unfortunately this function not destroy local objects in all stacks.

So what else can we do? This seems to be a common problem, and I'm sure
people have put much thought into it. Maybe some use of longjmp could help?

Here's my current solution, which seems to work in this special case in that
all sockets are closed, but there is no dynamic memory to release, file
handles to close, etc.
int global_s = -1;

void closesockets(in t sig)
{
if (global_s != -1)
{
closesocket(glo bal_s);
global_s = -1;
}
WSACleanup();
if (sig) exit(sig);
}

class CloseSockets
{
public:
CloseSockets() { WSADATA wsa; WSAStartup(MAKE WORD(1, 1), &wsa); }
~CloseSockets() { closesockets(0) ; }
private:
CloseSockets(co nst CloseSockets&); // not implemented
CloseSockets& operator=(const CloseSockets&); // not implemented
};
void server()
{
CloseSockets _closesockets;

int s = socket(AF_INET, SOCK_STREAM, 0);
if (s == -1) throw std::runtime_er ror("fail socket");

global_s = s;
signal(SIGINT , &closesocket s);
signal(SIGTERM, &closesocket s);
signal(SIGABRT, &closesocket s);

char myname[256];
int m = gethostname(myn ame, sizeof(myname)) ;

hostent * myhost = gethostbyname(m yname);
if (!myhost) throw std::runtime_er ror("no host");

// call to bind
// call to listen

while (true)
{
/* call to accept which creates a new socket */

while (true)
{
/* call to recv */
}

// call to closesocket
}
}
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.m oderated. First time posters: Do this! ]
Jul 22 '05 #1
13 4818
"Siemel Naran" <Si*********@RE MOVE.att.net> writes:
I want it so that when the user presses Ctrl-C or eds the task from
task manager (or the kill command in UNIX) then the system should
shutdown gracefully. This means it should call the destructors of
all objects, which means freeing dynamic memory, closing sockets,
closing file handles, close SQL connections, etc.

My approach was to set up a signal handler using std::signal. If
the signal handler does nothing the program resumes execution at the
point where the signal was raised (kind of like the RESUME command
in basic).

So one of my thoughts was to throw an exception in the signal
handler, [...] But we are not allowed to throw exceptions in signal
functions. [...]

My other thought was to call std::exit in the signal handler. But
unfortunately this function not destroy local objects in all stacks.

So what else can we do? This seems to be a common problem, and I'm
sure people have put much thought into it. Maybe some use of
longjmp could help?


Signal handlers need to use the POSIX functions sigsetjmp() and
siglongjmp() instead of setjmp() and longjmp(). Even so, destructors
for local instances won't be called. Mixing longjmp() and RAAI is
generally a bad idea.

One solution is to let the signal handler set a global variable
(declared as volatile sig_atomic_t), and check this variable regularly
inside all loops of long duration. If the variable is set, shutdown
can be initialized by throwing an exception or stopping the loop
normally. The disadvantage of this approach is that you have to do it
in *every* loop that might hang for some time, e.g. socket-reading
loops; you cannot restrict the shutdown implementation to the signal
handler. Also, you must be able to asynchronously stop or specify
timeouts for third-party functions that may be running when the signal
is received, since you probably won't be able to add shutdown checks
to loops contained in them.

Also, some Unix systems automatically restart interrupted system calls
if the signal handler returns. You can disable this behaviour by
using sigaction() instead of signal() and clearing the SA_RESTART
flag, in order to avoid that the system hangs in a restarted read()
call it was processing when Ctrl-C was received.

--
,------------------- Markus Bjartveit Krüger ---------------------.
' `
` E-mail: ma*****@pvv.org WWW: http://www.pvv.org/~markusk/ '
)-------------------------------------------------------------------(

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.m oderated. First time posters: Do this! ]
Jul 22 '05 #2
Siemel Naran wrote:

<summary>

When my program receives a KILL signal from the environment, how do I
make sure all "live" objects are destructed properly?

When the signal arrives, my handler function is entered. If I don't
exit the program explicitly from the handler, program execution will
resume wherever it was interrupted. I can't throw an exception from
the handler.

</summary>

The most common idiom seems to be the setting of a global variable,
which is then checked at strategic points in your program. Of course,
this is royally painful. An alternative would be having every resource
in the program allocated in a way that would allow explicit deallocation
from the signal handler; for example, there could be custom allocators
for memory, and factories for objects managing other resources.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.m oderated. First time posters: Do this! ]
Jul 22 '05 #3
"Siemel Naran" <Si*********@RE MOVE.att.net> wrote in message news:<Sx******* **************@ bgtnsc04-news.ops.worldn et.att.net>...
Hi. I posted this question to comp.lang.c++, but am rephrasing it a bit
from what I learned and posting to comp.lang.c++.m oderated for more insight.

So how do I solve my problem? I want it so that when the user presses
Ctrl-C or eds the task from task manager (or the kill command in UNIX) then
the system should shutdown gracefully. This means it should call the
destructors of all objects, which means freeing dynamic memory, closing
sockets, closing file handles, close SQL connections, etc.

My approach was to set up a signal handler using std::signal. If the signal
handler does nothing the program resumes execution at the point where the
signal was raised (kind of like the RESUME command in basic).

So one of my thoughts was to throw an exception in the signal handler, and
after returning control to the point in the function where the signal was
raised, the program would detect the exception and perform stack unwinding.
But we are not allowed to throw exceptions in signal functions. On my
compiler, Borland C++ 6 I get the message: << Project.exe faulted with
message "applicatio n-defined exception". Process Stopped. Use Step or Run to
continue. >>

My other thought was to call std::exit in the signal handler. But
unfortunately this function not destroy local objects in all stacks.

So what else can we do? This seems to be a common problem, and I'm sure
people have put much thought into it. Maybe some use of longjmp could help?

Here's my current solution, which seems to work in this special case in that
all sockets are closed, but there is no dynamic memory to release, file
handles to close, etc.
int global_s = -1;

void closesockets(in t sig)
{
if (global_s != -1)
{
closesocket(glo bal_s);
global_s = -1;
}
WSACleanup();
if (sig) exit(sig);
}

class CloseSockets
{
public:
CloseSockets() { WSADATA wsa; WSAStartup(MAKE WORD(1, 1), &wsa); }
~CloseSockets() { closesockets(0) ; }
private:
CloseSockets(co nst CloseSockets&); // not implemented
CloseSockets& operator=(const CloseSockets&); // not implemented
};
void server()
{
CloseSockets _closesockets;

int s = socket(AF_INET, SOCK_STREAM, 0);
if (s == -1) throw std::runtime_er ror("fail socket");

global_s = s;
signal(SIGINT , &closesocket s);
signal(SIGTERM, &closesocket s);
signal(SIGABRT, &closesocket s);

char myname[256];
int m = gethostname(myn ame, sizeof(myname)) ;

hostent * myhost = gethostbyname(m yname);
if (!myhost) throw std::runtime_er ror("no host");

// call to bind
// call to listen

while (true)
{
/* call to accept which creates a new socket */

while (true)
{
/* call to recv */
}

// call to closesocket
}
}


Maybe I miss something, but I do not see the need for
exceptions or the need for exit().

static bool return_from_ser ver = false;

extern "C" void signalhandler(i nt) {
return_from_ser ver = true;
}

struct WSASystem {
WSASystem() { WSADATA wsa; WSAStartup(MAKE WORD(1, 1), &wsa); }
~WSASystem() { WSACleanup(); }
};

class Socket {
const int x_;
public:
Socket(int x) : x_(x) {}
~Socket() { if (x_ != -1) closesocket(x_) ; }
int c_int() const { return x_; }
};

void server() {
const WSASystem wsa;

const Socket s(socket(AF_INE T, SOCK_STREAM, 0));
if (s.c_int() == -1) {
/* TODO: Give notice "fail socket" to some appropriate
information channel or up to the caller.
Although socket() claims it to be an error, for us the
situation is quite normal - we expect it to happen now
and then -, it is not an error nor an exception. */
return;
}

std::signal(SIG INT, &signalhandler) ;
std::signal(SIG TERM, &signalhandler) ;
std::signal(SIG ABRT, &signalhandler) ;

char myname[256];
const int m(gethostname(m yname, sizeof(myname)) );

hostent* const myhost(gethostb yname(myname));
if (myhost == 0) {
/* TODO: Give notice "no host" to some appropriate
information channel or up to the caller.
This situation is quite normal - we expect it to happen
now and then -, it is not an error nor an exception. */
return;
}

// call to bind
// call to listen

for (;;) {
if (return_from_se rver) {
return;
}
/* call to accept which creates a new socket */

for (;;) {
if (return_from_se rver) {
return;
}
/* call to recv */
}
}
}

Of course it is not complete at all (restoration of
signal handlers missing, ...).

Volker

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.m oderated. First time posters: Do this! ]
Jul 22 '05 #4
Siemel Naran wrote:
Hi. I posted this question to comp.lang.c++, but am rephrasing it a bit
from what I learned and posting to comp.lang.c++.m oderated for more insight.

So how do I solve my problem? I want it so that when the user presses
Ctrl-C or eds the task from task manager (or the kill command in UNIX) then
the system should shutdown gracefully. This means it should call the
destructors of all objects, which means freeing dynamic memory, closing
sockets, closing file handles, close SQL connections, etc.

My approach was to set up a signal handler using std::signal. If the signal
handler does nothing the program resumes execution at the point where the
signal was raised (kind of like the RESUME command in basic).
std::signal is not very useful due to the implementation-defined
behaviour when a second signal arrives, and IIRC "End Process" in
Windows does not cause a SIGINT. Look at the POSIX sigsetaction and
Win32 SetConsoleCtrlH andler functions instead. Note that console
handlers run in a separate thread, unlike signal handlers.
So one of my thoughts was to throw an exception in the signal handler, and
after returning control to the point in the function where the signal was
raised, the program would detect the exception and perform stack unwinding.
But we are not allowed to throw exceptions in signal functions.
Correct. Signals are in general *asynchronous*; they can interrupt
anything, just like a switch to another thread.

<snip> My other thought was to call std::exit in the signal handler. But
unfortunately this function not destroy local objects in all stacks.

<snip>

It also results in undefined behaviour.

However, since you're writing a network server which waits on
accept(), there is a solution - or rather, two similar solutions for
the two platforms I know. In the signal handler, you set a flag (of
type volatile sig_atomic_t under Unix, or using one of the interlocked
functions under Windows) and close() or closesocket() the listening
socket, causing accept() to fail. In error-handling for accept() you
check this flag (using an interlocked function under Windows). POSIX
guarantees that close() is safe in a signal handler (usually it is a
system call and so atomic w.r.t. signals). Under Windows I believe
the WinSock functions are all thread-safe.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.m oderated. First time posters: Do this! ]
Jul 22 '05 #5
"Markus B. Krüger" <ma*****@pvv.or g> wrote in message
"Siemel Naran" <Si*********@RE MOVE.att.net> writes:
I want it so that when the user presses Ctrl-C or eds the task from
task manager (or the kill command in UNIX) then the system should
shutdown gracefully. This means it should call the destructors of
all objects, which means freeing dynamic memory, closing sockets,
closing file handles, close SQL connections, etc.

One solution is to let the signal handler set a global variable
(declared as volatile sig_atomic_t), and check this variable regularly
inside all loops of long duration. If the variable is set, shutdown
can be initialized by throwing an exception or stopping the loop
normally. The disadvantage of this approach is that you have to do it
in *every* loop that might hang for some time, e.g. socket-reading
loops; you cannot restrict the shutdown implementation to the signal
handler.
Yes, this was the advice I received in my original post to comp.lang.c++.
It's quite error-prone though because you might forget to put these checks
as you write the code. As you write your code, you add new loops,
re-arrange code, etc, and inserting these checks is the last thing on your
mind.

Perhaps one could use macros

#define } if (g_signal) throw Signal(__FILE__ , __LINE__); }

The above tells the pre-processor that it should replace } with a check on
the global variable followed by the real }. But could this be a misuse of
macros? Anyway, not sure if the macro expansion is legal -- ie. not sure if
we can #define } or {. We could always use

#define END if (g_signal) throw Signal(__FILE__ , __LINE__); }

Second, what is the deal with sig_atomic_t? What's so special about it?
Also, you must be able to asynchronously stop or specify
timeouts for third-party functions that may be running when the signal
is received, since you probably won't be able to add shutdown checks
to loops contained in them.
Sorry, I don't understand. Can you elaborate?
Also, some Unix systems automatically restart interrupted system calls
if the signal handler returns. You can disable this behaviour by
using sigaction() instead of signal() and clearing the SA_RESTART
flag, in order to avoid that the system hangs in a restarted read()
call it was processing when Ctrl-C was received.
What do you mean by "interrupte d system calls"? Also, my signal.h does not
have sigaction and SA_RESTART.
Signal handlers need to use the POSIX functions sigsetjmp() and
siglongjmp() instead of setjmp() and longjmp(). Even so, destructors
for local instances won't be called. Mixing longjmp() and RAAI is
generally a bad idea.


Why is mixing longjmp and RAAI bad? In C++ style we usually declare
variables as we need them, initializing them at the same time. So a call to
longjmp may skip the initialization of objects or initialize the same object
twice. As long as we declare all variables at the top of the function and
then call setjmp, as in the C style, it should be fine to use longjmp. Is
this correct?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.m oderated. First time posters: Do this! ]
Jul 22 '05 #6
"Jeff Schwab" <je******@comca st.net> wrote in message
news:q9mdnYMdOZ 3elT_dRVn-
The most common idiom seems to be the setting of a global variable,
which is then checked at strategic points in your program. Of course,
this is royally painful. An alternative would be having every resource
in the program allocated in a way that would allow explicit deallocation
from the signal handler; for example, there could be custom allocators
for memory, and factories for objects managing other resources.


This idea of overloading new operators is very interesting. So then you'd
store the address of the object in a global registry, and at program
termination you free the objects in the registries? Maybe you could
register the registries with atexit (or with an object that is registered
with atexit). (For DLLs you could register with DLLMain where the reason is
DLL_PROCESS_DET ACH.)

Has anyone actually done this? What is involved, how difficult is it to
implement, what burderns does it impose on developers using the framework,
what are the performance costs?

As QoI, we'd expect the compiler implementation to free all dynamic memory
at program termination. How many actually do this? And how many close file
handles and sockets?

Anyway, we could for example overload global operator new and delete, and
force users to use these functions to acquire and free memory. They
shouldn't use std::malloc directly as this is not overloadable. Right?

Similarly we could overload FileStream::ope rator new to get memory and store
this memory in the registry. In FileStream::ope rator delete we free the
memory and remove it from the registry.

But what if someone creates a Fuile
class FileStream {
public:
class FailOpen;
FileStream(cons t char * filename) { d_file = fopen(filename) ; if (!file)
throw FailOpen(); }
virtual ~FileStream() { fclose(d_file); }
static void * operator new(size_t n) {
s_list.push_bac k(NULL); // create space in list first, as this itself
may throw
FileStream * ptr = std::malloc(n); // create memory
d_list.back() = ptr; // store memory in list
}
static void operator delete(void * v, size_t n) {
find 'v' in s_list;
erase from s_list;
}
private:
FILE * d_file;
static std::list<FileS tream *> s_list;
static void cleanup() {
for (each element in s_list) delete element;
s_list.clear();
}
FileStream(cons t FileStream&);
FileStream& operator=(const FileStream&);
};

std::atexit(&Fi leStream::clean up);
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.m oderated. First time posters: Do this! ]
Jul 22 '05 #7
Jeff Schwab <je******@comca st.net> wrote in message
news:<q9******* *************@c omcast.com>...
Siemel Naran wrote: <summary> When my program receives a KILL signal from the environment, how do
I make sure all "live" objects are destructed properly? When the signal arrives, my handler function is entered. If I
don't exit the program explicitly from the handler, program
execution will resume wherever it was interrupted. I can't throw
an exception from the handler. </summary> The most common idiom seems to be the setting of a global variable,
which is then checked at strategic points in your program. Of course,
this is royally painful. An alternative would be having every
resource in the program allocated in a way that would allow explicit
deallocation from the signal handler; for example, there could be
custom allocators for memory, and factories for objects managing other
resources.


This isn't usually possible. You cannot call free() in a signal
handler, for example. Nor fclose, nor I would imagine
std::ofstream:: close(). Nor exit(). According to the standard, you can
in fact do very little. Most implementations guarantee more, but the
examples I just gave are forbidden by Posix as well.

In a multithreaded application under Unix, you can set things up so that
the signal is handled by a special thread, rather than in a traditional
signal handler. This thread can then call pthread_cancel on the other
threads; on some implementations , at least, this does do a stack
walkback on the thread.

But that it is all very system specific.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.m oderated. First time posters: Do this! ]
Jul 22 '05 #8
"Siemel Naran" <Si*********@RE MOVE.att.net> writes:
"Markus B. Krüger" <ma*****@pvv.or g> wrote in message
> One solution is to let the signal handler set a global variable
> (declared as volatile sig_atomic_t), and check this variable
> regularly inside all loops of long duration. [...]
Yes, this was the advice I received in my original post to
comp.lang.c++. It's quite error-prone though because you might
forget to put these checks as you write the code. As you write your
code, you add new loops, re-arrange code, etc, and inserting these
checks is the last thing on your mind.

Perhaps one could use macros

#define } if (g_signal) throw Signal(__FILE__ , __LINE__); }


This makes it impossible to write loops that *shouldn't* be
interrupted by shutdown. Perhaps a solution would be a couple of
macros

#define BEGIN_INTERRUPT ABLE {
#define END_INTERRUPTAB LE } \
if (g_signal) throw Signal(__FILE__ , __LINE__);

and use these macros to start and end blocks that should be
interruptable by shutdown.
[...] what is the deal with sig_atomic_t? What's so special about
it?
Since a signal might arrive while you're reading from or writing to a
variable, you need a type that is guaranteed to be atomic with regard
to signal processing, so that you do not read partially updated data.
> Also, you must be able to asynchronously stop or specify timeouts
> for third-party functions that may be running when the signal is
> received, since you probably won't be able to add shutdown checks
> to loops contained in them.


Sorry, I don't understand. Can you elaborate?


Let's say you're using a third party library for retrieving URLs, and
that you call a function getUrl(). This function would then wrap up
the connection to the web server and reading from the socket. If a
signal arrives while getUrl() is running, you need a way to make the
third party library aware that it should stop processing, since you
cannot insert the shutdown checks into the third party library
yourself. (Unless, of course, you have access to the source code, or
want to dabble with reverse engineering.)
What do you mean by "interrupte d system calls"?
If a signal arrives while the system is processing a system call, such
as connect() or read(), the signal may interrupt the system call,
depending on your operating system. When this happens, your operating
system might restart the system call, return a partial success (for
instance, if some data had been read by read() when the signal
arrived), or let the system call return an error code and set errno to
EINTR.
Also, my signal.h does not have sigaction and SA_RESTART.
sigaction() is part of POSIX.1. If your platform is not POSIX.1
compatible, this function might not be available to you.
Why is mixing longjmp and RAAI bad?


Because destructors for objects currently on the stack will not be
called when you longjmp(). Simple code to illustrate the problem
follows; note that the destructor of instance a is not called as it
should be.

#include <csetjmp>
#include <iostream>

using namespace std;

class A
{
public:
A() { cout << "A::A() called" << endl; }
~A() { cout << "A::~A() called" << endl; }
};

int main(int argc, char **argv)
{
jmp_buf env;
if (setjmp(env)) {
cout << "longjmp() called, terminating" << endl;
return 0;
}

// The destructor of the following instance should be called,
// but it isn't.
A a;

longjmp(env, 1);
}

--
,------------------- Markus Bjartveit Krüger ---------------------.
' `
` E-mail: ma*****@pvv.org WWW: http://www.pvv.org/~markusk/ '
)-------------------------------------------------------------------(

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.m oderated. First time posters: Do this! ]
Jul 22 '05 #9
"Siemel Naran" <Si*********@RE MOVE.att.net> writes:
[snip]
Why is mixing longjmp and RAAI bad?
RAII.
In C++ style we usually declare
variables as we need them, initializing them at the same time. So a call to
longjmp may skip the initialization of objects or initialize the same object
twice. As long as we declare all variables at the top of the function and
then call setjmp, as in the C style, it should be fine to use longjmp. Is
this correct?


longjmp does not call destructors.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.m oderated. First time posters: Do this! ]
Jul 22 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
2403
by: Andrew Athan | last post by:
I have a python program (snippet below) which does not want to seem to die when I issue a sys.exit() inside the SIGTERM handler. The output below is generated as the result of sending several SIGTERM signals to the process, as a result of seeing that it had not died. I don't think this is relevant, but the application has fork()ed a child...
12
533
by: Siemel Naran | last post by:
(1) About std::exit. If I call this function, will the system call the destructors of all objects in the call stack. Eg. void f() { std::exit(1); } void g() { X x; f(); } Does the call in f() to std::exit invoke x.~X() in scope g()? (2) About signals and exceptions. Is it possible to throw an exception from
4
28987
by: Bryan | last post by:
Quick question: Why does os._exit called from a Python Timer kill the whole process while sys.exit does not? On Suse. Bryan
4
1684
by: Mantorok Redgormor | last post by:
Should I just avoid them? I have heard many bad things about them 1) if you set a signal handler, you can't really ignore the signal and continue with normal program execution, because after that undefined behavior is invoked. 2) if you have a signal handler set for say SIG_INT and you continue to reset the handler after you received the...
4
1692
by: Joe Van Dyk | last post by:
The C++ language doesn't deal with signals (i.e. SIGINT, SIGKILL), right? Joe
6
66492
by: Vicky | last post by:
Please tell me at vdkhakhkhar@gmail.com
2
1765
by: Ian | last post by:
Monitor::Enter and Monitor::Exit must be called in pairs. Is there a way to determine if Monitor::Exit has been called so that it does not get called a second time? The psuedocode below illustrates a situation I would like to implement. Essentially there are 2 monitors and the first monitor can be released in 2 different locations. This...
4
1798
by: lovecreatesbea... | last post by:
Is the following code (without any code at lines x and x + 3) correct? Is it better to call exit() or re-throw the exceptions at line x and line x + 3?. What is the better code should we place at line x and line x + 3? try { cnn = env->createConnection(user, pwd, db); } catch (SQLException &esql){ cerr << "DB Exception: " <<...
11
1806
by: vippstar | last post by:
What is the purpose of signals and why do they exist in C? thanks in advance
34
4989
by: Drake | last post by:
I have a general question of Python style, or perhaps just good programming practice. My group is developing a medium-sized library of general-purpose Python functions, some of which do I/O. Therefore it is possible for many of the library functions to raise IOError Exceptions. The question is: should the library function be able to just...
0
7478
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7668
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
7773
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
5984
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
1
5343
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
4960
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3466
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3448
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
722
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.