如何在c中使用线程中止程序?

时间:2015-01-09 15:56:55

标签: multithreading pthreads

我已经编写了该程序,该程序正在扫描文件夹,并希望在用户输入“q'”时始终停止运行。在胜利它简单 - getch()功能。在Linux中,它更难做到,如果我想在win和linux中运行我的程序,我的老师告诉我使用线程。问题是如何?我已经写过像这样的文字:

void exit_stat()
{
            int x=0;
    char d;
    while(x==0)
    {
        d=getchar();
        if(d=='q')
        exit;
    }
}

并在主要:

pthread_t threads[1];
pthread_create(&threads[0], NULL, exit_stat, NULL);

如何解决?

2 个答案:

答案 0 :(得分:1)

你需要exit(0);,如果你exit;(概念上)查找一个函数指针,然后抛出它而不调用它。致电exit相当于从return执行main

答案 1 :(得分:0)

你可以让你的main()监视stdin,然后当它收到用户的'q'命令时,让它告诉你的扫描线程消失。在C ++中你可以使用std :: atomic boolean来很容易地做到这一点,但是既然你问过C,这里有一个使用套接字对来做通知的解决方案。特别是,当main()线程希望scan_thread终止时,它通过关闭自己的套接字对连接结束来表示需要。 scan_thread检测到连接已关闭,并通过终止自身来响应。

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/socket.h>

static void * scan_thread(void * socketPtr)
{
   int socket1 = *((int *)socketPtr);

   while(1)
   {
      printf("scan_thread:  I'm scanning more files!\n");
      sleep(1);  /* well, I'm pretending to, anyway */

      /* See if the main thread has closed his end of the socket-connection yet.
       * If so, that means it is time for us to clean up and exit.
       */
      char buf;
      int r = recv(socket1, &buf, 1, 0);
      if (r == 0) break;  /* recv() returning 0 indicates that the socket connection has been broken */
   }
   printf("scan_thread is exiting now!\n");

   close(socket1);  /* make sure we don't leak our socket */
   return NULL;
}

int main(int argc, char ** argv)
{
   /** Create a pair of sockets that are connected to each other */
   int sockets[2];
   if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets) != 0)
   {
      perror("socketpair");
      return 10;
   }

   /** Make socket[1] non-blocking so that the scan_thread can check its status without blocking */
   int flags = fcntl(sockets[1], F_GETFL, 0);
   if (fcntl(sockets[1], F_SETFL, flags|O_NONBLOCK) != 0)
   {
      perror("fcntl");
      return 10;
   }

   /** spawn the child thread.  Pass him a pointer to his socket, as an argument. */
   pthread_t thread;
   if (pthread_create(&thread, NULL, scan_thread, &sockets[1]) != 0)
   {
      perror("pthread_create");
      return 10;
   }

   char buf[128];
   while(fgets(buf, sizeof(buf), stdin))
   {
      if (buf[0] == 'q')
      {
         printf("You typed q, time to abort the thread!\n");
         break;
      }
   }

   /** Close our socket.  That will let the scan_thread know its time for him to exit. */
   close(sockets[0]);

   /** Wait for the scan_thread to exit (this is important, to avoid race conditions). */
   (void) pthread_join(thread, NULL);

   printf("main() is ending, bye!\n");
   return 0;
}

但请注意,您的老师对于必要的线程并不完全正确;通过将stdin设置为非阻塞模式,您可以从Linux下的stdin获得非阻塞读取行为。这是一个程序的例子,它可以在不产生任何额外线程的情况下执行相同的操作:

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

int main(int argc, char ** argv)
{
   /** Set stdin to non-blocking mode so we can read from it without blocking */
   int fd = fileno(stdin);
   int flags = fcntl(fd, F_GETFL, 0);
   if (fcntl(fd, F_SETFL, flags|O_NONBLOCK) != 0)
   {
      perror("fcntl");
      return 10;
   }

   while(1)
   {
      printf("I'm scanning more files!\n");
      sleep(1);  /* well, I'm pretending to, anyway */

      char buf[128];
      if ((fgets(buf, sizeof(buf), stdin))&&(buf[0] == 'q'))
      {
         printf("You entered q, exiting now!\n");
         break;
      }
   }
   return 0;
}