Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
130 views
in Technique[技术] by (71.8m points)

c - one thread to exit them all

I have a main program that generates a few threads (using a while loop with accept() to get clients), and one that all it has to do is "listen to the keyboard" and when the user enters the word exit it will close the entire program. first, the main program create the listening thread, then it enters a while loop that accept the clients. even if the listening thread get the exit input the loop is still stuck on accept.

i don't have to use a seperate thread to listen to the keyboard but i could'nt find a none blocking way that would work.

the listening thread:

DWORD WINAPI ListenService(LPVOID lpParam)
{
    char buffer[5];
    if (EOF == scanf("%s", buffer))
    {
        printf("faile get word from keyboard
");
    }
    if (buffer[4] != '')
        strcat(buffer, "");
    if (STRINGS_ARE_EQUAL(buffer, "exit"))
    {
        return 999;
    }
    return -1;
}

in the main code:

ThreadListen = CreateThread(NULL,0,ListenService,NULL,0,&(ThreadId));   
while(1)
{
    SOCKET AcceptSocket = accept(MainSocket, NULL, NULL);
    if (AcceptSocket == INVALID_SOCKET)
    {
        printf("Accepting connection with client failed, error %ld
", WSAGetLastError());
        CleanupWorkerThreads();
        WSACleanup();
    }
    printf("Client Connected.
");
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

There are many different ways you can handle this.

You can abort a blocked accept() by simply closing the listening socket.

Or, you can use select() with a short timeout to detect when a new client is waiting before then calling accept(). You can check your exit condition in between calls to select(). Just be aware that there is a small race condition where a client may disconnect between the time select() and accect() are called, so accept() may still block, if there are no more clients waiting.

Or, you can get rid of your threads and just use non-blocking sockets in a single thread, checking your exit condition periodically in between socket operations.

Or, you can use asynchronous sockets, using WSACreateEvent(), WSAEventSelect(), and WSAWaitForMultipleEvents() to detect socket activity. Then you can create an addition event to wait on for when the exit condition happens.

Or, you can use an I/O Completion Port to handle socket activity, and then you can post a custom exit packet into the IOCP queue using PostQueuedCompletionStatus() to "wake up" any waiting threads.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...