Chinaunix首页 | 论坛 | 博客
  • 博客访问: 702344
  • 博文数量: 152
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1793
  • 用 户 组: 普通用户
  • 注册时间: 2013-09-12 12:26
个人简介

相信自己,只有不想做的,没有做不到的。

文章分类

全部博文(152)

文章存档

2021年(1)

2015年(2)

2014年(74)

2013年(75)

分类: LINUX

2013-12-16 21:37:42

三 线程同步

POISX线程间同步机制使用的是信号量机制;
信号量代表一类资源,信号量的值资源的个数;

POISX线程间的同步用的是无名信号量,用sem_t类型描述
例如: sem_t read_sem,write_sem;

注意:信号量是一个受保护的变量,不能直接操作,必须通过一下接口操作

A.初始化信号量的值

int sem_init(sem_t *sem, int pshared, unsigned int value);
第一个参数:需要操作信号量的地址
第二个参数:线程间使用,默认为 0
第三个参数:要初始化的值

B.P操作(申请资源)
int sem_wait(sem_t *sem);

C.V操作(释放资源)
int sem_post(sem_t *sem);


#include
#include
#include
#include
#include
#include
#include
#include
#include

sem_t read_sem,write_sem;

void init_semaphore(sem_t *psem,int value)
{
 if(sem_init(psem,0,value) < 0)
 {
  perror("Fail to sem_init");
  exit(EXIT_FAILURE);
 }

 return;
}

void P(sem_t *psem)
{
 if(sem_wait(psem) < 0)
 {
  perror("Fail to sem_wait");
  exit(EXIT_FAILURE);
 }

 return;
}

void V(sem_t *psem)
{
 if(sem_post(psem) < 0)
 {
  perror("Fail to sem_post");
  exit(EXIT_FAILURE);
 }

 return;
}

void *read_thread(void *arg)
{
 int n;
 char buf[1024];
 int fd = *((int *)arg);
 int last_offset = 0;

 while(1)
 {
  
  //申请读资源
  P(&read_sem); 

  lseek(fd,last_offset,SEEK_SET);

  n = read(fd,buf,sizeof(buf) - 1);
  buf[n]  = '\0';
 
  printf("Read %d bytes : %s.\n",n,buf);

  if(strncmp(buf,"quit",4) == 0)
   break;

  last_offset = lseek(fd,0,SEEK_CUR);

  //释放写资源
  V(&write_sem);
 }

 pthread_exit(NULL);
}

void *write_thread(void *arg)
{
 char buf[1024];
 int fd = *((int *)arg);

 while(1)
 {
  P(&write_sem);

  fgets(buf,sizeof(buf),stdin);
  buf[strlen(buf) - 1] = '\0';

  write(fd,buf,strlen(buf));  

  V(&read_sem);
  
  if(strncmp(buf,"quit",4) == 0)
   break;
 }

 pthread_exit(NULL);
}

//./a.out file
int main(int argc, const char *argv[])
{
 int ret;
 int fd;
 pthread_t tid[2];

 if(argc < 2)
 {
  fprintf(stderr,"Usage : %s argv[1].\n",argv[0]);
  exit(EXIT_FAILURE);
 }

 if((fd = open(argv[1],O_RDWR | O_CREAT | O_TRUNC,0666)) < 0)
 {
  fprintf(stderr,"Fail to open %s : %s.\n",argv[1],strerror(errno));
  exit(EXIT_FAILURE);
 }

 init_semaphore(&read_sem,0);
 init_semaphore(&write_sem,1);
 
 ret = pthread_create(&tid[0],NULL,read_thread,(void *)&fd);
 if(ret != 0){
  perror("Fail to pthread_create");
  exit(EXIT_FAILURE);
 }

 ret = pthread_create(&tid[1],NULL,write_thread,(void *)&fd);
 if(ret != 0){
  perror("Fail to pthread_create");
  exit(EXIT_FAILURE);
 }

 pthread_join(tid[0],NULL);
 pthread_join(tid[1],NULL);

 exit(EXIT_SUCCESS);
}


 

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