Unix高级环境编程系列笔记

发表于:2013-11-18来源:IT博客大学习作者:nebula点击数: 标签:Unix
1. 如何来标识一个线程? 表示进程号的为pid_t类型,表示线程号的是pthread_t类型。pthread_t是一个结构体而不是整型。

  1. 如何来标识一个线程?

  表示进程号的为pid_t类型,表示线程号的是pthread_t类型。pthread_t是一个结构体而不是整型。

  使用pthread_equal确定两个线程号是否相等:

  #include

  int pthread_equal(pthread_t tid1, pthread_t tid2);

  Returns: nonzero if equal, 0 otherwise

  使用pthread_self函数来获取线程的ID:

  #include

  pthread_t pthread_self(void);

  Returns: the thread ID of the calling thread

  2.如何创建一个新线程?

  使用pthread_create函数创建一个新线程。

以下是代码片段:
#include 
int pthread_create(pthread_t *restrict tidp, const pthread_attr_t *restrict attr, void *(*start_rtn)(void), void *restrict arg);
Returns: 0 if OK, error number on failure

  当该函数成功返回的时候,tidp所指向的内存位置将被分配给新创建的带有thread ID的线程。

  attr用来定制各种线程参数。

  新创建的线程将在start_rtn函数所指向的地址开始运行,该函数接受一个参数无类型的指针arg作为参数

  线程创建时无法保证哪个线程会先运行。新创建的线程可以访问进程地址空间,并且继承了调用线程的浮点环境以及信号量掩码,但对于线程的未决信号量也将会被清除。

  下面的这段程序创建新的线程,并打印线程id,新线程通过pthread_self函数获取自己的线程ID。

  #include "apue.h"

  #include

  pthread_t ntid;

  void printids(const char *s)

  {

  pid_t pid;

  pthread_t tid;

  pid = getpid();

  tid = pthread_self();

  printf("%s pid %u tid %u (0x%x)\\n", s, (unsigned int)pid,

  (unsigned int)tid, (unsigned int)tid);

  }

  void * thr_fn(void *arg)

  {

  printids("new thread: ");

  return((void *)0);

  }

  int main(void)

  {

  int err;

  err = pthread_create(&ntid, NULL, thr_fn, NULL);

  if (err != 0)

  err_quit("can\'t create thread: %s\\n", strerror(err));

  printids("main thread:");

  sleep(1);

  exit(0);

  }

  3. 如何实现单个线程的退出?

  如果一个线程调用了exit, _Exit, 或者_exit,将导致整个进程的终止。要实现单个线程的退出,可以采用如下方式:

  o 线程可以简单的从start routine返回,返回值就是线程的退出代码。

  o 线程可以被同一进程中的其它线程终止。

  o 线程调用pthread_exit

  #include

  void pthread_exit(void *rval_ptr);

  4.如何使调用线程阻塞等待指定线程的退出,并获得退出线程的返回码?

  #include

  int pthread_join(pthread_t thread, void **rval_ptr);

  Returns: 0 if OK, error number on failure

  调用线程将会被阻塞直到指定的线程终止。如果线程简单的从start routine返回则rval_ptr将包含返回代码。如果线程是被撤销(调用pthread_exit)的,rval_ptr指向的内存地址将被设置为PTHREAD_CANCELED.

  通过调用pthread_join,我们自动的将一个线程变成分离状态,这样就可以实现资源的回收。如果线程已经处于分离状态,调用pthread_join将会失败,并返回EINVAL。

  如果我们对于线程的返回值不感兴趣,可以将rval_ptr设置成NULL。

  一段有缺陷的代码:

  #include "apue.h"

  #include

  struct foo {

  int a, b, c, d;

  };

  void

  printfoo(const char *s, const struct foo *fp)

  {

  printf(s);

  printf(" structure at 0x%x\\n", (unsigned)fp);

  printf(" foo.a = %d\\n", fp->a);

  printf(" foo.b = %d\\n", fp->b);

  printf(" foo.c = %d\\n", fp->c);

  printf(" foo.d = %d\\n", fp->d);

  }

  void *

  thr_fn1(void *arg)

  {

  struct foo foo = {1, 2, 3, 4};

  printfoo("thread 1:\\n", &foo);

  pthread_exit((void *)&foo);

  }

  void *

  thr_fn2(void *arg)

  {

  printf("thread 2: ID is %d\\n", pthread_self());

  pthread_exit((void *)0);

  }

  int

  main(void)

  {

  int err;

  pthread_t tid1, tid2;

原文转自:http://blogread.cn/it/article/3344