C语言细致讲解线程同步的集中方式_第1页
C语言细致讲解线程同步的集中方式_第2页
C语言细致讲解线程同步的集中方式_第3页
C语言细致讲解线程同步的集中方式_第4页
C语言细致讲解线程同步的集中方式_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第C语言细致讲解线程同步的集中方式目录互斥锁条件变量信号量读写锁

互斥锁

使用互斥量完成对临界区的资源的加锁操作,使得同一时刻,对一个共享数据的使用只能又一个线程完成

例向屏幕上一次打印abcd四个字母

可以使用的是一个类似锁连的思想a加完解开后拿b锁依次类推

#defineTHRNUM4

staticpthread_mutex_tmut[4];

staticintnext(intn)

if(n+1==THRNUM)

return0;

returnn+1;

staticvoid*pthreadfunc(void*p)

intn=(int)p;

charc='a'+(int)p;

while(1)

pthread_mutex_lock(mut+n);

write(1,c,1);

pthread_mutex_unlock(mut+next(n));

pthread_exit(NULL);

intmain()

inti,err;

pthread_ttid[THRNUM];

//创建线程

for(i=0;iTHRNUM;i++){

//初始化锁

pthread_mutex_init(mut+i,NULL);

//加锁

pthread_mutex_lock(mut+i);

err=pthread_create(tid+i,NULL,pthreadfunc,(void*)i);

if(err!=0)

fprintf(stderr,"create:%s\n",strerror(err));

exit(1);

//回收线程

pthread_mutex_unlock(mut+0);

alarm(5);

for(i=0;iTHRNUM;i++){

pthread_join(tid+i,NULL);

}

条件变量

条件变量并不是锁而是一种阻塞机制,使得我们的程序在某些特定的条件,比如生产者生产达到上限未消费,此时使用条件变量(加上while对条件的判断)来阻塞生产,让生产者消费

#includestdio.h

#includeunistd.h

#includepthread.h

#includestdlib.h

#includestring.h

intbegnum=0;

staticpthread_mutex_tmut=PTHREAD_MUTEX_INITIALIZER;

staticpthread_cond_tcond=PTHREAD_COND_INITIALIZER;

typedefstruct_prodinfo

intnum;

struct_prodinfo*next;

}prod;

struct_prodinfo*head=NULL;

/*条件变量可以引起阻塞并非锁

void*thr_produce(void*arg)

while(1)

prod*pd=malloc(sizeof(struct_prodinfo));

pd-num=begnum++;

pthread_mutex_lock(mut);

pd-next=head;

head=pd;

printf("-%ld号线程生产%d产品\n",pthread_self(),pd-num);

pthread_mutex_unlock(mut);

pthread_cond_signal(cond);

sleep(rand()%4);

void*thr_con(void*arg)

prod*pro=NULL;

while(1)

pthread_mutex_lock(mut);

while(head==NULL)

pthread_cond_wait(cond,mut);

pro=head;

head=head-next;

printf("-%ld号线程消费%d产品\n",pthread_self(),pro-num);

pthread_mutex_unlock(mut);

free(pro);

sleep(rand()%4);

intmain()

pthread_tcid,pid;

interr1=pthread_create(pid,NULL,thr_produce,NULL);

if(err1)

fprintf(stderr,"pthread_creat():%s\n",strerror(err1));

exit(1);

interr2=pthread_create(cid,NULL,thr_con,NULL);

if(err2)

fprintf(stderr,"pthread_creat():%s\n",strerror(err1));

exit(1);

pthread_join(pid,NULL);

pthread_join(cid,NULL);

}

信号量

介绍以下信号量是进化版的互斥量,允许多个线程访问共享资源与条件变量和互斥量类此的操作,在进程和线程中均可以使用

intsem_init(sem_t*sem,intpshared,unsignedintvalue);

intsem_destroy(sem_t*sem);

Linkwith-pthread.

sem为定义的信号量,传出型参数

pshared

0代表线程信号量1代表进程信号量

alue为定义的信号量个数

intsem_wait(sem_t*sem);

intsem_trywait(sem_t*sem);

intsem_timedwait(sem_t*sem,conststructtimespec*abs_timeout);

申请信号量,申请成功value,当value为0则阻塞

intsem_post(sem_t*sem);

释放信号量value++

例信号量实现生产者消费者模型

sem_tpro_sem,con_sem;

#definesemcnt5

inti=0;

intqueue[semcnt];

intbeginnum=100;

void*thr_produce(void*arg)

while(1)

sem_wait(pro_sem);//生产者申请资源pro_sem每被占用一次--一次当为0时则阻塞

printf("%ld线程生产了%d\n",pthread_self(),beginnum);

queue[(i++)%semcnt]=beginnum++;

sem_post(con_sem);//为消费者的信号量释放资源pro_sem每被释放一次++一次

sleep(rand()%4);

returnNULL;

void*thr_con(void*arg)

inti=0;

intnum=0;

while(1)

sem_wait(con_sem);

num=queue[(i++)%semcnt];

printf("%ld线程消费了%d\n",pthread_self(),num);

sem_post(pro_sem);

sleep(rand()%3);

returnNULL;

intmain()

sem_init(pro_sem,0,semcnt);

sem_init(con_sem,0,0);//消费者初始默认没有产品

pthread_ttid[2];

interr1=pthread_create(tid[0],NULL,thr_produce,NULL);

if(err1)

fprintf(stderr,"pthread_creat():%s\n",strerror(err1));

exit(1);

interr2=pthread_create(tid[1],NULL,thr_con,NULL);

if(err2)

fprintf(stderr,"pthread_creat():%s\n",strerror(err1));

exit(1);

pthread_join(tid[0],NULL);

pthread_join(tid[1],NULL);

sem_destroy(pro_sem);

sem_destroy(con_sem);

}

读写锁

读写锁与互斥量类似,但是读写锁允许更高的并行性,其特性为:写独占,读共享

读写锁实质上是一把锁,有不同的状态,写锁的优先级高

读写锁的三种状态

读模式下加锁(读锁)写模式下加锁(写锁)不加锁状态

读写锁的特性:读锁可以共享读的状态,当读锁加上时,阻塞写锁的加锁

即使读锁加上时后面的写锁依然会被阻塞,当前面读锁释放时才能加成功

pthread_rwlock_trwlock=PTHREAD_RWLOCK_INITIALIZER;

intbeginum=100;

void*thr_Wr(void*arg)

while(1)

pthread_rwlock_wrlock(rwlock);

printf("-写线程--beginum=%d\n",beginum++);

usleep(2000);//模拟占用时间

pthread_rwlock_unlock(rwlock);

usleep(2000);//简单防止再抢锁的方法但不建议使用

returnNULL;

void*thr_ead(void*arg)

while(1)

pthread_rwlock_rdlock(rwlock);

printf("-读读线程--beginum=%d\n",beginum);

usleep(2000);//模拟占用时间

pthread_rwlock_unlock(rwlock);

usleep(2000);//简单防止再抢锁的方法但不建议使用

returnNULL;

intmain()

intn=8,i=

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论