posix thread,

  posix thread,

  当我们第一次学习线程时,我们没有讨论线程属性。我们现在将进行讨论。线程有许多我们可以控制的属性。但是,这里我们只讨论那些我们最需要的线程属性。其他属性的详细信息可以在手册中找到。

  在我们之前的所有例子中,在允许程序退出之前,我们必须使用pthread_join来重新同步我们的线程。如果我们想让一个线程将数据返回给创建它的线程,我们需要这样做。有时候我们不需要第二个线程向主线程返回信息,也不希望主线程等待第二个线程。

  假设我们创建第二个线程来备份正在编辑的数据文件的副本,而主线程继续为用户服务。当备份完成时,第二个线程简单地退出,不需要与主线程聚合。

  我们可以创建这样的线程。它们被称为分离线程,我们可以通过修改线程属性或一致地调用pthread_detach来创建这样的线程。因为我们想在这里演示线程属性,所以我们将使用前一种方法。

  我们需要的最重要的函数是pthread_attr_init,它可以初始化一个线程属性对象。

  #include pthread.h

  int pthread _ attr _ init(pthread _ attr _ t * attr);

  同样,如果成功,它将返回0,如果失败,它将返回一个错误代码。

  还有一个销毁函数:pthread_attr_destroy。此功能的目的是允许清除属性对象。一旦对象被销毁,该属性对象在初始化之前不能再次使用。

  当我们有一个初始化的线程属性时,我们可以调用许多额外的函数来设置不同的属性行为。我们在这里列出了一些主要函数,但是我们只知道其中的两个:

  int pthread _ attr _ setdetachstate(pthread _ attr _ t * attr,int detachstate);

  int pthread _ attr _ getdetachstate(const pthread _ attr _ t * attr,int * detachstate);

  int pthread _ attr _ setschedpolicy(pthread _ attr _ t * attr,int policy);

  int pthread _ attr _ getschedpolicy(const pthread _ attr _ t * attr,int * policy);

  int pthread _ attr _ setschedparam(pthread _ attr _ t * attr,const struct sched_param

  * param);

  int pthread _ attr _ getschedparam(const pthread _ attr _ t * attr,struct sched_param

  * param);

  int pthread _ attr _ setinheritsched(pthread _ attr _ t * attr,int inherit);

  int pthread _ attr _ getinheritsched(const pthread _ attr _ t * attr,int * inherit);

  int pthread _ attr _ set scope(pthread _ attr _ t * attr,int scope);

  int pthread _ attr _ get scope(const pthread _ attr _ t * attr,int * scope);

  int pthread _ attr _ setstacksize(pthread _ attr _ t * attr,int scope);

  int pthread _ attr _ getstacksize(const pthread _ attr _ t * attr,int * scope);

  正如我们所看到的,有许多属性我们可以使用,但幸运的是,我们通常不会使用其中的大部分。

  Detachstate:这个属性允许我们避免线程重新聚合的需要。像大多数_set函数一样,它将一个指向属性的指针和一个确定所需状态的标志作为参数。pthread_attr_setdetachstate函数的两个可能的标记值是PTHREAD_CREATE_JOINABLE和PTHREAD_CRATE_DETACHED。默认情况下,属性值是PTHREAD_CREATE_JOINABLE,这样我们就可以允许两个线程重新聚合。如果状态设置为PTHREAD_CRATE_DETACHED,我们就不能调用pthread_joi来恢复另一个线程的退出状态。

  Schedpolicy:该属性控制如何调度线程。选项有SCHED_OTHER、SCHED_RR和SCHED_FIFO。默认情况下,属性值为SCHED_OTHER。其他两种调度类型仅在以超级用户权限运行时可用,因为它们都有实时调度,但它们的行为略有不同。SCHED_RR使用循环调度,而SCHED_FIFO使用先进先出策略。对这些属性的讨论超出了本书的范围。

  Schedparam:这是schedpolicy的合作伙伴,它允许我们控制使用SCHED_OTHER策略运行的线程的调度。我们将在本章后面看到一个使用这个参数的例子。

  Inheritsched:这个属性有两个可能的值:PTHREAD_EXPLICIT_SCHED和PTHREAD_INHERIT_SCHED。默认情况下,属性值为PTHREAD_EXPLICIT_SCHED,这意味着调度是通过属性显示来设置的。通过将其设置为PTHREAD_INHERIT_SCHED,新线程将使用其创建者线程使用的参数。

  Scope:该属性控制如何计算线程的调度。目前Linux只支持PTHREAD_SCOPE_SYSTEM,这里就不讨论这个特性了。

  Stacksize:该属性控制线程创建堆栈的大小,以字节为单位设置。这是规范的“可选”部分,仅在定义了_POSIX_THREAD_ATTR_STACKSIZE的实现中受支持。Linux默认使用大堆栈来实现线程,所以这个特性在Linux上通常很丰富。

  测试-设置分离状态属性。

  作为我们分离线程的一个例子,thread5.c,我们创建了一个线程属性,将其设置为分离属性,然后使用这个属性创建一个线程。现在,当子线程完成时,他以正常方式调用pthread_exit函数。但是,这一次原始线程不再等待与他创建的线程重新聚合。我们使用一个简单的thread_finished标记来允许主线程检测子线程是否已经结束,并显示线程仍然共享变量。

  #包含stdio.h

  #包含stdlib.h

  #包含字符串. h

  #包括unistd.h

  #include pthread.h

  void * thread _ function(void * arg);

  char message[]= Hello World ;

  int thread _ finished=0;

  int main()

  {

  int res

  pthread _ t a _ thread

  pthread _ attr _ t thread _ attr

  RES=pthread _ attr _ init(thread _ attr);

  if(res!=0)

  {

  perror(属性创建失败);

  退出(EXIT _ FAILURE);

  }

  RES=PTHREAD _ attr _ setdetachstate(thread _ attr,PTHREAD _ CREATE _ DETACHED);

  if(res!=0)

  {

  perror(“设置分离的属性失败”);

  退出(EXIT _ FAILURE);

  }

  res=pthread_create( a_thread,thread_attr,thread_function,(void *)message);

  if(res!=0)

  {

  perror(“线程创建失败”);

  退出(EXIT _ FAILURE);

  }

  (void)pthread _ attr _ destroy(thread _ attr);

  而(!线程_已完成)

  {

  printf(等待线程说完成./n’);

  睡眠(1);

  }

  printf( oth thread线程完成,拜拜!/n’);

  退出(EXIT _ SUCCESS);

  }

  void *thread_function

  {

  printf(thread_function正在运行。参数是%s/n ,(char *)arg);

  睡眠(4);

  printf(第二线程设置完成标志,现在退出/n );

  thread _ finished=1;

  pthread_exit(空);

  }

  正如我们所看到的,设置分离状态允许第二个线程独立完成,而无需主线程等待第二个线程。

  两个重要的代码段是:

  pthread _ attr _ t thread _ attr

  RES=pthread _ attr _ init(thread _ attr);

  if (res!=0) {

  perror(属性创建失败);

  退出(EXIT _ FAILURE);

  }

  这将声明一个线程属性并初始化它。另一个代码是:

  RES=PTHREAD _ attr _ setdetachstate(thread _ attr,PTHREAD _ CREATE _ DETACHED);

  if (res!=0) {

  perror(“设置分离的属性失败”);

  退出(EXIT _ FAILURE);

  }

  这段代码将属性值设置为分离状态。

  另一个区别是创建一个线程,在那里传递属性地址。

  res=pthread_create( a_thread,thread_attr,thread_function,(void

  *)消息);

  为了完整起见,当我们使用完这个属性时,我们需要销毁这个属性:

  pthread _ attr _ destroy(thread _ attr);

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: