【发布时间】:2011-01-29 23:45:16
【问题描述】:
Linux 上的套接字问题
我有一个工作线程在接受() 调用时被阻塞。它只是等待传入的网络连接,处理它,然后返回侦听下一个连接。
当程序退出时,我如何向这个网络工作线程(来自主线程)发出信号,使其从 accept() 调用返回,同时仍然能够优雅地退出其循环并处理其清理代码。
我尝试过的一些事情:
pthread_kill 发送信号。这样做感觉很笨拙,而且它不能可靠地允许线程执行它的关闭逻辑。也使程序终止。如果可能的话,我想避免信号。
pthread_cancel。和上面一样。这是对线程的严厉杀戮。那,线程可能正在做其他事情。
从主线程关闭监听套接字以使 accept() 中止。这并不可靠。
一些限制:
如果解决方案涉及使侦听套接字非阻塞,那很好。但我不想接受涉及每隔几秒通过 select 调用唤醒线程以检查退出条件的解决方案。
退出的线程条件可能与退出的进程无关。
基本上,我要寻找的逻辑是这样的。
void* WorkerThread(void* args)
{
DoSomeImportantInitialization(); // initialize listen socket and some thread specific stuff
while (HasExitConditionBeenSet()==false)
{
listensize = sizeof(listenaddr);
int sock = accept(listensocket, &listenaddr, &listensize);
// check if exit condition has been set using thread safe semantics
if (HasExitConditionBeenSet())
{
break;
}
if (sock < 0)
{
printf("accept returned %d (errno==%d)\n", sock, errno);
}
else
{
HandleNewNetworkCondition(sock, &listenaddr);
}
}
DoSomeImportantCleanup(); // close listen socket, close connections, cleanup etc..
return NULL;
}
void SignalHandler(int sig)
{
printf("Caught CTRL-C\n");
}
void NotifyWorkerThreadToExit(pthread_t thread_handle)
{
// signal thread to exit
}
int main()
{
void* ptr_ret= NULL;
pthread_t workerthread_handle = 0;
pthread_create(&workerthread, NULL, WorkerThread, NULL);
signal(SIGINT, SignalHandler);
sleep((unsigned int)-1); // sleep until the user hits ctrl-c
printf("Returned from sleep call...\n");
SetThreadExitCondition(); // sets global variable with barrier that worker thread checks on
// this is the function I'm stalled on writing
NotifyWorkerThreadToExit(workerthread_handle);
// wait for thread to exit cleanly
pthread_join(workerthread_handle, &ptr_ret);
DoProcessCleanupStuff();
}
【问题讨论】:
-
pthread_kill()向线程发送信号,仅此而已。而且它不一定“使程序终止”。 -
"pthread_cancel。同上。" Err,什么?不,
pthread_cancel()做的事情与pthread_kill()完全不同!请 RTFM。 -
让accept() 返回的一种简单方法是打开一个TCP 连接到accept() 调用正在侦听的端口。