介绍
函数
pthread_create()
pthread_exit()
pthread_join()
线程同步
信号量同步

介绍

函数

pthread_create()

这个函数创建一个线程,原型如下:

#include <pthread.h>

int pthread_create (pthread_t *thread, pthread_attr_t *attr,\
       void * (*start_routine) (void *), void *arg);

一共需要四个参数传递给 pthread_create 函数,调用成功返回 0,否 则返回其他值。

线程标识符
这是第一个参数,是一个指针,指向一个 pthread_t 类型的数据。创建一个线程的时候,这个指针指向的变 量里面会被写入一个标识符,以后可以通过这个标识符来引用此线 程。
线程属性
第二个参数设置线程的属性,通常可以传递 NULL 给这个参数。
执行函数
第三个参数就是本线程要执行的函数,这是一个函数指 针,这个函数的形参可以是任何类型的指针(void ),返回值也可 以是任何类型的指针 (void )。
传递给执行函数的参数
第四个参数是一个指向任意类型的指针, 传递给第三个参数作为参数。

pthread_exit()

pthread_exit() 用于线程退出,可以指定返回值,以便其他线程通过 pthread_join() 函数获取该线程的返回值。 return ,是函数返回, 不一定是线程函数! 只有线程函数 return,线程才会退出 exit() 是进程退出,如果在线程函数中调用 exit ,那此线程的进程也就挂了。 会导致该线程所在进程的其他线程也挂掉,比较严重。

#include <pthread.h>

void pthread_exit ( void *retval );

pthread_join()

相当于进程中的 wait() 函数,第一个参数是要等待的线程,它是用 pthread_create() 创建的线程标识符。第二个参数是一个指针,这个指 针指向线程的返回值。成功返回0,出错返回错误代码。

#include <pthread.h>

int pthread_join (pthread_t th, void **thread_return);

线程同步

信号量同步

信号量函数名字都以 sem_ 开头,线程中使用的基本信号量函数有四个。

创建信号量 sem_init()

#include <semaphore.h>

int sem_init (set_t *sem, int pshared, unsigned int value);

对由 sem 指定的信号量进行初始化,设置好它的共享项,给它一个整数 类型的初始值。 pshared 参数控制着信号量的类型,如果其值为0,则 表示它是当前进程的局部信号量;否则,其他进程就可以共享这个信号量。

sem_wait() 和 sem_post()

#include <semaphore.h>

int sem_wait( set_t *sem);
int sem_post( set_t *sem);

sem_post() 给信号量的值加上一个 "1"; sem_wait() 给一个信号量减 去 "1",永远等待信号量的值不为零才执行这个动作。

清理信号量 sem_destroy()

#include <semaphore.h>

int sem_destroy (sem_t * sem);

下面的例子是《Linux程序设计》上的,略作修改。这个例子用到了我们 上面介绍的函数。能很好的理解线程间的信号量通信方式。记住,初始 化信号量一般设置其值为0,等待的线程如果需要其他“线程”先执行,以 便得到自己想要的数据,就使用 sem_wait() 函数等待。别的线程在准 备好数据后,就使用 sem_post() 函数增加信号量的值。最后注销创建 的信号量是个好习惯!

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <semaphore.h>
#include <pthread.h>

void * thread_func (void *arg);
sem_t bin_sem;

#define WORK_SIZE 1024
char work_area[WORK_SIZE];

int main()
{
  int res;
  pthread_t thread_one;
  void *thread_result;

  res=sem_init(&bin_sem,0,0);
  if (res != 0)
  {
    perror("信号初始化失败!");
    exit(EXIT_FAILURE);
  }

  res=pthread_create(&thread_one,NULL,thread_func,NULL);
  if (res != 0)
  {
    perror("线程创建失败!");
    exit(EXIT_FAILURE);
  }

  printf("输入一些字符,以'EOF'结束\n");
  while(strncmp("EOF",work_area,3) != 0)
  {
    fgets(work_area,WORK_SIZE,stdin);
    sem_post(&bin_sem);
  }

  printf("\n等待线程结束...\n");
  res=pthread_join(thread_one,&thread_result);
  if (res != 0)
  {
    perror("等待线程结束失败!");
    exit(EXIT_FAILURE);
  }

  printf("线程结束!\n");
  sem_destroy(&bin_sem);
  exit(EXIT_SUCCESS);
}

void * thread_func (void *arg)
{
  sem_wait(&bin_sem); /*bin_sem的初始值为0,此处就是等待其值不为0*/
  while(strncmp("EOF",work_area,3) != 0)
  {
    printf("你输入了%d个字节的文本\n",strlen(work_area)-1);
    sem_wait(&bin_sem);
  }
  pthread_exit(NULL);
}