Linux多线程编程(一)

2019-10-14 13:18:03丽君


写加锁: 

int pthread_rwlock_wrlock (pthread_rwlock_t *__rwlock)


解锁用同一个函数:

int pthread_rwlock_unlock (pthread_rwlock_t *__rwlock)

3、条件变量条件变量用pthread_cond_t数据类型表示。条件变量本身由互斥量保护,所以在改变条件状态前必须锁住互斥量。
条件变量初始化:
第一种,赋值常量PTHREAD_COND_INITIALIZER;第二种,使用pthread_cond_init函数

int pthread_cond_init (pthread_cond_t *__restrict __cond,
   __const pthread_condattr_t *__restrict
   __cond_attr);int pthread_cond_destroy (pthread_cond_t *__cond);


条件等待
使用pthread_cond_wait等待条件为真。

 pthread_cond_wait (pthread_cond_t *__restrict __cond,
   pthread_mutex_t *__restrict __mutex)

这里需要注意的是,调用pthread_cond_wait传递的互斥量已锁定,pthread_cond_wait将调用线程放入等待条件的线程列表,然后释放互斥量,在pthread_cond_wait返回时,再次锁定互斥量。
唤醒线程
pthread_cond_signal唤醒等待该条件的某个线程,pthread_cond_broadcast唤醒等待该条件的所有线程。

int pthread_cond_signal (pthread_cond_t *__cond);
int pthread_cond_broadcast (pthread_cond_t *__cond)


来一个例子,主线程启动4个线程,每个线程有一个参数i(i=生成顺序),无论线程的启动顺序如何,执行顺序只能为,线程0、线程1、线程2、线程3。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#define DEBUG 1

int num=0;
pthread_mutex_t mylock=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t qready=PTHREAD_COND_INITIALIZER;
void * thread_func(void *arg)
{
  int i=(int)arg; 
  int ret;
  sleep(5-i);//线程睡眠,然最先生成的线程,最后苏醒
  pthread_mutex_lock(&mylock);//调用pthread_cond_wait前,必须获得互斥锁
  while(i!=num)
  {
#ifdef DEBUG
    printf("thread %d waitingn",i);
#endif
    ret=pthread_cond_wait(&qready,&mylock);//该函数把线程放入等待条件的线程列表,然后对互斥锁进行解锁,这两部都是原子操作。并且在pthread_cond_wait返回时,互斥量再次锁住。
    if(ret==0)
    {
#ifdef DEBUG
      printf("thread %d wait successn",i);
#endif
    }else
    {
#ifdef DEBUG
      printf("thread %d wait failed:%sn",i,strerror(ret));
#endif
    }
  }
  printf("thread %d is running n",i);
  num++;
  pthread_mutex_unlock(&mylock);//解锁
  pthread_cond_broadcast(&qready);//唤醒等待该条件的所有线程
  return (void *)0;
}
int main(int argc, char** argv) {
  
  int i=0,err;
  pthread_t tid[4];
  void *tret;
  for(;i<4;i++)
  {
    err=pthread_create(&tid[i],NULL,thread_func,(void *)i);
    if(err!=0)
    {
      printf("thread_create error:%sn",strerror(err));
      exit(-1);
    }
  }
  for (i = 0; i < 4; i++)
  {
    err = pthread_join(tid[i], &tret);
    if (err != 0)
    {
      printf("can not join with thread %d:%sn", i,strerror(err));
      exit(-1);
    }
  }
  return 0;
}