mutex是一个互斥锁对象,互斥锁是为了防止多线程同时修改某一公共资源,我在下面的程序里把它“锁”在了一个叫buffer[10]的缓冲区 上,模型是2个Reader和2个Writer,Reader要等到叫buffer的书架上有书的时候才可以read,而Writer也必须在书架没有放 满的情况下才可以把新写的书放到书架上。我的程序里书架的大小是1,当然也可以设置书架的大小,不过实现过程大同小异。就不多说了。来看程序:
#i nclude <stdio.h> #i nclude <pthread.h> void reader_function(void); void writer_function(void); char buffer[10]={0}; int buffer_has_item=0; pthread_mutex_t mutex; int main(void) { pthread_t reader; /* 用默认属性初始化一个互斥锁对象*/ pthread_mutex_init (&mutex,NULL); pthread_create(&reader,NULL, (void *)reader_function, NULL); writer_function(); } void writer_function(void) { int i,ti; for(i=1;i<3;) { ti=i; /* 锁定互斥锁*/ pthread_mutex_lock(&mutex); printf("Writer %d Locked Buffer. ",i); if (buffer_has_item==0) { buffer_has_item=1; strcpy(buffer,"Full"); printf("++Writer %d fill the buffer with context " %s". ",i,buffer); i++; } /* 打开互斥锁*/ printf("Writer %d Unlocked Buffer. ",ti); pthread_mutex_unlock(&mutex); sleep(1); } } void reader_function(void) { int i,ti; for(i=1;i<3;) { ti=i; pthread_mutex_lock(&mutex); printf("Reader %d Locked Buffer. ",i); if(buffer_has_item==1) { buffer_has_item=0; strcpy(buffer,"Empty"); printf("--Reader %d clean the buffer with context "%s". ",i,buffer); i++; } printf("Reader %d Unlocked Buffer. ",ti); pthread_mutex_unlock(&mutex); sleep(1); } }
编译:gcc -o mutex -lpthread -g mutex.c 运行:./mutex 结果: Reader 1 Locked Buffer. Reader 1 Unlocked Buffer.
Writer 1 Locked Buffer. ++Writer 1 fill the buffer with context "Full". Writer 1 Unlocked Buffer.
Writer 2 Locked Buffer. Writer 2 Unlocked Buffer.
Reader 1 Locked Buffer. --Reader 1 clean the buffer with context "Empty". Reader 1 Unlocked Buffer.
Writer 2 Locked Buffer. ++Writer 2 fill the buffer with context "Full". Writer 2 Unlocked Buffer.
Reader 2 Locked Buffer. --Reader 2 clean the buffer with context "Empty". Reader 2 Unlocked Buffer.
注意,这次用到的sleep()不再是为了让结果好看, 而是为了防止一个线程始终占用资源,很多网上的教程使用的是pthread_delay_np(&delay);这个语句,不过这个似乎只能在 solaris系统上用,linux还是用sleep()和usleep()好了,有高人说可能会使该线程所在的进程都sleep,我使用下来似乎没有发 现。而且似乎linux下本来就是一个进程里只有一个线程,忘记哪个手册上说的,也许是以前的版本,不追究了,能用就行。
还 有就是在reader()和writer()里,我用了很奇怪的 i 和 ti 两个变量来对reader和writer编号,主要目的是为了保证每个Reader和Writer都能完成自己的使命,如果按照常规写法,使用for(i =1;i<3;i++)这样控制循环会使有的Reader或者Writer不能取到或者放上书。似乎说得自己都迷糊了,举例说,Reader1去取 书,恰巧这时候书架上是空的,为了保证Reader1能取到书,我就让Reader们排队,直到Reader1取到以后才轮到Reader2,对于 Writer们也实行排队
http://hi.baidu.com/%BC%D0%B2%E3%D6%D0%B5%C4%BB%B0%CC%E2/blog/item/fff6a21e8f36e91f40341706.html