Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在Linux中何时使用pthread_exit()以及何时使用pthread_join()?_C_Linux_Pthreads - Fatal编程技术网

C 在Linux中何时使用pthread_exit()以及何时使用pthread_join()?

C 在Linux中何时使用pthread_exit()以及何时使用pthread_join()?,c,linux,pthreads,C,Linux,Pthreads,我不熟悉pthreads,我正在努力理解它。我看到了如下一些例子 我可以看到main()被APIpthread\u exit()阻塞,我还看到了主函数被APIpthread\u join()阻塞的示例。我不明白什么时候用什么 我指的是以下网站-。我不知道何时使用pthread\u join()以及何时使用pthread\u exit() 有人能解释一下吗?此外,对于pthreads的良好教程链接也将不胜感激 #include <pthread.h> #include <stdi

我不熟悉pthreads,我正在努力理解它。我看到了如下一些例子

我可以看到
main()
被API
pthread\u exit()
阻塞,我还看到了主函数被API
pthread\u join()阻塞的示例。我不明白什么时候用什么

我指的是以下网站-。我不知道何时使用
pthread\u join()
以及何时使用
pthread\u exit()

有人能解释一下吗?此外,对于pthreads的良好教程链接也将不胜感激

#include <pthread.h>
#include <stdio.h>
#define NUM_THREADS     5

void *PrintHello(void *threadid)
{
   long tid;
   tid = (long)threadid;
   printf("Hello World! It's me, thread #%ld!\n", tid);
   pthread_exit(NULL);
}

int main (int argc, char *argv[])
{
   pthread_t threads[NUM_THREADS];
   int rc;
   long t;
   for(t=0; t<NUM_THREADS; t++){
      printf("In main: creating thread %ld\n", t);
      rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
      if (rc){
         printf("ERROR; return code from pthread_create() is %d\n", rc);
         exit(-1);
      }
   }

   /* Last thing that main() should do */
   pthread_exit(NULL);
有时,您希望在线程执行时取消它。 可以使用pthread_cancel(thread);。 但是,请记住,您需要启用pthread cancel支持。 此外,取消时还需要一个清理代码

thread_cleanup_push(my_thread_cleanup_handler, resources);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);

static void my_thread_cleanup_handler(void *arg)
{
  // free
  // close, fclose
}

pthread_exit
终止调用线程,而
pthread_join
暂停调用线程的执行,直到目标线程完成执行

OpenGroup文档中对它们进行了非常详细的解释:


您不需要在特定代码中调用

一般来说,
main
线程不应该调用
pthread\u exit
,而应该经常调用以等待其他线程完成

PrintHello
函数中,您不需要调用
pthread\u exit
,因为它在返回后是隐式的

因此,您的代码应该是:

void *PrintHello(void *threadid)  {
  long tid = (long)threadid;
  printf("Hello World! It's me, thread #%ld!\n", tid);
  return threadid;
}

int main (int argc, char *argv[]) {
   pthread_t threads[NUM_THREADS];
   int rc;
   intptr_t t;
   // create all the threads
   for(t=0; t<NUM_THREADS; t++){
     printf("In main: creating thread %ld\n", (long) t);
     rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
     if (rc) { fprintf(stderr, "failed to create thread #%ld - %s\n",
                                (long)t, strerror(rc));
               exit(EXIT_FAILURE);
             };
   }
   pthread_yield(); // useful to give other threads more chance to run
   // join all the threads
   for(t=0; t<NUM_THREADS; t++){
      printf("In main: joining thread #%ld\n", (long) t);
      rc = pthread_join(&threads[t], NULL);
      if (rc) { fprintf(stderr, "failed to join thread #%ld - %s\n",
                                (long)t, strerror(rc));
               exit(EXIT_FAILURE);
      }
   }
}
void*PrintHello(void*threadid){
长tid=(长)线程ID;
printf(“你好,世界!是我,线程#%ld!\n”,tid);
返回threadid;
}
int main(int argc,char*argv[]){
pthread_t threads[NUM_threads];
int rc;
intptr\t;
//创建所有线程

对于(t=0;t,这两种方法都确保进程不会在所有线程结束之前结束

join方法让
main
函数的线程显式地等待所有要“连接”的线程

pthread\u exit
方法以受控方式终止您的
main
函数和线程。
main
的特殊性是,如果不终止
main
,则将终止您的整个进程,包括所有其他线程

要使此方法起作用,必须确保没有线程使用在其
main
函数中声明的局部变量。该方法的优点是
main
不必知道进程中已启动的所有线程,例如,因为其他线程自己创建了新的线程
main
什么都不知道。

POSIX pthread_退出
说明来自:


这似乎与本地main()线程变量将保持可访问性的想法相反。

如openpub文档中所述

将退出调用它的线程

在您的情况下,由于主线程调用它,主线程将终止,而派生的线程将继续执行 主线程只需要生成线程并让线程完成其工作

将挂起调用它的线程的执行,除非目标线程终止

当您希望等待线程终止后再进一步执行时,这非常有用 在主线程中处理。

pthread_exit()API 如前所述,用于调用线程终止。 调用该函数后,将启动复杂的清理机制。 当它完成时,线程被终止。 在pthread_create()创建的线程中调用return()例程时,也会隐式调用pthread_exit()API。 实际上,对return()的调用和对pthread_exit()的调用具有相同的影响,从pthread_create()创建的线程调用

区分main()函数启动时隐式创建的初始线程和pthread_create()创建的线程非常重要。 main()函数对return()例程的调用隐式调用exit()系统调用,整个过程终止。 没有启动线程清理机制。 从main()函数调用pthread_exit()会导致清理机制启动,当它完成工作时,初始线程终止

当从main()函数调用pthread_exit()时,整个进程(以及其他线程)的情况取决于pthread实现。 例如,在IBM OS/400实现中,当从main()函数调用pthread_exit()时,整个进程(包括其他线程)将终止。 其他系统的行为可能不同。 在大多数现代Linux机器上,从初始线程调用pthread_exit()不会终止整个进程,直到所有线程终止。 如果要编写可移植应用程序,请小心使用main()中的pthread_exit()。

pthread_join()API 是等待线程终止的一种方便方法。 您可以编写自己的函数来等待线程终止,这可能更适合您的应用程序,而不是使用pthread_join()。 例如,它可以是一个基于等待条件变量的函数

我建议您阅读David R.Butenhof的《使用POSIX线程编程》一书 它很好地解释了讨论的主题(以及更复杂的事情)(尽管有些实现细节,例如主函数中的pthread_exit用法,并不总是反映在书中)。

pthread_exit()
将终止调用线程并退出该线程(但若并没有从主线程分离,那个么调用线程使用的资源不会释放到操作系统中。)

pthrade_join()
将等待或阻止调用
void *PrintHello(void *threadid)  {
  long tid = (long)threadid;
  printf("Hello World! It's me, thread #%ld!\n", tid);
  return threadid;
}

int main (int argc, char *argv[]) {
   pthread_t threads[NUM_THREADS];
   int rc;
   intptr_t t;
   // create all the threads
   for(t=0; t<NUM_THREADS; t++){
     printf("In main: creating thread %ld\n", (long) t);
     rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
     if (rc) { fprintf(stderr, "failed to create thread #%ld - %s\n",
                                (long)t, strerror(rc));
               exit(EXIT_FAILURE);
             };
   }
   pthread_yield(); // useful to give other threads more chance to run
   // join all the threads
   for(t=0; t<NUM_THREADS; t++){
      printf("In main: joining thread #%ld\n", (long) t);
      rc = pthread_join(&threads[t], NULL);
      if (rc) { fprintf(stderr, "failed to join thread #%ld - %s\n",
                                (long)t, strerror(rc));
               exit(EXIT_FAILURE);
      }
   }
}
After a thread has terminated, the result of access to local (auto) variables of the thread is 
undefined. Thus, references to local variables of the exiting thread should not be used for 
the pthread_exit() value_ptr parameter value.
  #include<stdio.h>
  #include<pthread.h>
  #include<semaphore.h>
 
   sem_t st;
   void *fun_t(void *arg);
   void *fun_t(void *arg)
   {
       printf("Linux\n");
       sem_post(&st);
       //pthread_exit("Bye"); 
       while(1);
       pthread_exit("Bye");
   }
   int main()
   {
       pthread_t pt;
       void *res_t;
       if(pthread_create(&pt,NULL,fun_t,NULL) == -1)
           perror("pthread_create");
       if(sem_init(&st,0,0) != 0)
           perror("sem_init");
       if(sem_wait(&st) != 0)
           perror("sem_wait");
       printf("Sanoundry\n");
       //Try commenting out join here.
       if(pthread_join(pt,&res_t) == -1)
           perror("pthread_join");
       if(sem_destroy(&st) != 0)
           perror("sem_destroy");
       return 0;
   }
void *fun_t(void *arg)
   {
       printf("Linux\n");
       sem_post(&st); 
       if(2-1 == 1)  
           pthread_exit("Bye");
       else
       { 
           printf("We have a problem. Computer is bugged");
           pthread_exit("Bye"); //This is redundant since the thread will exit at the end
                                //of scope. But there are instances where you have a bunch
                                //of else if here.
       }
   }

#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>

sem_t st;

void* fun_t (void* arg)
{
    printf("I'm thread\n");
    sem_post(&st);
}

int main()
{
    pthread_t pt;
    pthread_create(&pt,NULL,fun_t,NULL);
    sem_init(&st,0,0);
    sem_wait(&st);
    printf("before_thread\n");
    pthread_join(pt,NULL);
    printf("After_thread\n");
    
}