Chinaunix首页 | 论坛 | 博客
  • 博客访问: 554905
  • 博文数量: 99
  • 博客积分: 5015
  • 博客等级: 大校
  • 技术积分: 1209
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-28 23:08
文章存档

2011年(7)

2010年(6)

2009年(86)

我的朋友

分类: LINUX

2009-08-27 16:53:27

注:非常感谢big_zhang老师的指点,下面就把有关的东西共享给大家
 
一个线程存数据,由另一个线程读数据,这个是要加锁的,否则这两个线程怎么同步啊.
你可以使用下面的架构模型:

存数据线程:
pthread_mutex_lock加锁.
pthread_cond_wait 等待数组有空间.

存放数据处理
pthread_cond_signal 告诉读线程, 数组里放置了数据
pthread_mutex_unlock 释放锁.

读数据线程:
pthread_mutex_lock 加锁
pthread_cond_wait 等待数组里有数据
读取数据处理
pthread_cond_signal 告知存放数据线程,已经读取记录,也就是腾出了数组的一个空间.
pthread_mutex_unlock 解锁.

以上模型,两个线程通过 pthread_cond_signal通讯.
pthread_cond_wait分别是线程的等待点.
 
下面是其C实现(C++的实现请参考big_zhang老师的博客里的两篇文章,讲得很详细

# include <limits.h>
# include <pthread.h>
# include <stdlib.h>
# include <stdio.h>
   
# define MAXNTHREADS 100
# define NBUFF 20
    
typedef struct {
  pthread_cond_t cond;
  int resource;
} Cond;
    
typedef struct {
  pthread_t id;
  int seq;
} Data;
    
Cond getCond = { PTHREAD_COND_INITIALIZER, 0 };
Cond putCond = { PTHREAD_COND_INITIALIZER, NBUFF };
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    
Data buff[NBUFF];
int front = 0;
int rear = 0;
int size = 0;
    
int run = 1;
    
void stop()
{
  run = 0;
    
  pthread_mutex_lock(&mutex);
    
  getCond.resource = INT_MAX / 2;
  pthread_cond_broadcast(&getCond.cond);
  putCond.resource = INT_MAX / 2;
  pthread_cond_broadcast(&putCond.cond);
    
  pthread_mutex_unlock(&mutex);
}
    
int
put(const Data* data)
{
  pthread_mutex_lock(&mutex);
    
  while( putCond.resource < 1 )
    pthread_cond_wait(&putCond.cond, &mutex);
  putCond.resource--;
    
  if ( run ) {
    buff[rear] = *data;
    rear = (rear + 1) / NBUFF;
    size++;
  }
    
  getCond.resource++;
  pthread_cond_signal(&getCond.cond);
  pthread_mutex_unlock(&mutex);
  return run;
}
    
int
get(Data* data)
{
  int rc;
    
  pthread_mutex_lock(&mutex);
    
  while( getCond.resource < 1 )
    pthread_cond_wait(&getCond.cond, &mutex);
  getCond.resource--;
    
  if ( size != 0 ) {/* not empty */
    *data = buff[front];
    front = (front + 1) % NBUFF;
    size--;
    
    rc = 1;
  } else
    rc = 0;
    
  putCond.resource++;
  pthread_cond_signal(&putCond.cond);
  pthread_mutex_unlock(&mutex);
    
  return rc;
}
    
int nitems, nputs, ngets;
    
void *
put_thread(void *arg)
{
  Data data;
    
  data.id = pthread_self();
    
  for ( data.seq = 0; data.seq < nitems; data.seq++ ) {
    put(&data);
    *((int *)arg) += 1;
  }
    
  return 0;
}
    
void *
get_thread(void *arg)
{
  pthread_t tid;
  Data data;
    
  tid = pthread_self();
    
  while( get(&data) ) {
    printf("%lu %lu %d\n", tid, data.id, data.seq);
    *((int *)arg) += 1;
  }
    
  return 0;
}
    
int
main(int argc, char **argv)
{
  int i, p, g;
  int putcount[MAXNTHREADS], getcount[MAXNTHREADS];
  pthread_t tid_put[MAXNTHREADS], tid_get[MAXNTHREADS];
    
  if ( argc < 4 ) {
    fprintf(stderr, "Usage: %s <#items> <#put> <#get>\n", argv[0]);
    return -1;
  }
    
  nitems = atoi(argv[1]);
  nputs = atoi(argv[2]);
    
  if ( nputs > MAXNTHREADS )
    nputs = MAXNTHREADS;
    
  ngets = atoi(argv[3]);
    
  if ( ngets > MAXNTHREADS )
    ngets = MAXNTHREADS;
    
  printf("Item: <%d> Puts: <%d> Gets: <%d>\n", nitems, nputs, ngets);
    
  for ( i = 0; i < nputs; i++ ) {
    putcount[i] = 0;
    pthread_create(&tid_put[i], 0, put_thread, &putcount[i]);
  }
    
  for ( i = 0; i < ngets; i++ ) {
    getcount[i] = 0;
    pthread_create(&tid_get[i], 0, get_thread, &getcount[i]);
  }
    
  p = 0;
  for ( i = 0; i < nputs; i++ ) {
    pthread_join(tid_put[i], 0);
    printf("Put %lu count[%d] = %d\n", tid_put[i], i, putcount[i]);
    p += putcount[i];
  }
    
  stop();
    
  g = 0;
  for ( i = 0; i < ngets; i++ ) {
    pthread_join(tid_get[i], 0);
    g += getcount[i];
    printf("Get %lu count[%d] = %d\n", tid_get[i], i, getcount[i]);
  }
    
  printf("Get %d Put %d\n", g, p);
    
  return 0;
}

本文来自CSDN博客,转载请标明出处:http:

阅读(1295) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~