对象 | 操作 | Linux Pthread API | Windows SDK 库对应 API |
---|---|---|---|
线程 | 创建 | pthread_create | CreateThread |
退出 | pthread_exit | ThreadExit | |
等待 | pthread_join | WaitForSingleObject | |
互斥锁 | 创建 | pthread_mutex_init | CreateMutex |
销毁 | pthread_mutex_destroy | CloseHandle | |
加锁 | pthread_mutex_lock | WaitForSingleObject | |
解锁 | pthread_mutex_unlock | ReleaseMutex | |
条件 | 创建 | pthread_cond_init | CreateEvent |
销毁 | pthread_cond_destroy | CloseHandle | |
触发 | pthread_cond_signal | SetEvent | |
广播 | pthread_cond_broadcast | SetEvent / ResetEvent | |
等待 | pthread_cond_wait / pthread_cond_timedwait | SingleObjectAndWait |
功能:生产者生产按顺序依次生产16辆汽车,同时工厂只能存放16辆汽车;消费者按顺序依次提取那16辆汽车。在汽车生产满16辆时,停止生产,直到消费者提取汽车,有空的位置存放汽车才能开始生产汽车。
方案:建立一个结构体存储汽车数量及位置,互斥锁,空满信号struct prodcons buffer;
建立两个线程:一个是生产者生产汽车producer(),一个是消费者提取汽车consumer();
建立两个函数:一个用来生产汽车put(),另一个用来提取汽车get();
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<time.h>
#include<pthread.h>
#define OVER (-1)
#define BUFFER_SIZE 16
struct prodcons buffer;
/* 设置一个整数的圆形缓冲区 */
struct prodcons{
int buffer[BUFFER_SIZE]; /* 缓冲去数组*/
pthread_mutex_t lock; /* 互斥锁 */
int readpos,writepos; /* 读写的位置*/
pthread_cond_t notempty; /*缓冲区的非空信号*/
pthread_cond_t notfull; /*缓冲区非满信号*/
};
/* 初始化缓冲信号*/
void init(struct prodcons *b)
{
pthread_mutex_init(&b->lock,NULL);
pthread_cond_init(&b->notempty,NULL);
pthread_cond_init(&b->notfull,NULL);
b->readpos = 0;
b->writepos = 0;
}
/* 向缓冲区写入一个整数*/
void put(struct prodcons *b,int data)
{
pthread_mutex_lock(&b->lock);
/* 等待缓冲区非满 */
while((b->writepos +1)%BUFFER_SIZE == b->readpos){
/*当缓冲区的位置56789...15, 1234存在信息 而readpos位于缓冲区的第5位置,此时缓冲区的所有位置都写满了信息,需要等待readpos读取信息,防止writepos位于readpos之后,把未读取的信息覆盖掉。*/
printf("wait for not full\n");
pthread_cond_wait(&b->notfull,&b->lock);
}
/* 向缓冲区写入信息 ,写的位置后移一位 */
b->buffer[b->writepos] = data;
b->writepos++;
if(b->writepos>=BUFFER_SIZE) b->writepos = 0;
/* 发送有一个非空信号,之后解开互斥锁 */
pthread_cond_signal(&b->notempty);
pthread_mutex_unlock(&b->lock);
}
/* 从缓冲区读取数值 */
int get(struct prodcons *b){
int data;
pthread_mutex_lock(&b->lock);
/* */
while(b->writepos == b->readpos){
printf("wait for not empty\n");
pthread_cond_wait(&b->notempty,&b->lock);
}
/* */
data = b->buffer[b->readpos];
b->readpos++;
if(b->readpos>=BUFFER_SIZE) b->readpos=0;
/* */
pthread_cond_signal(&b->notfull);
pthread_mutex_unlock(&b->lock);
return data;
}
void *producer(void *data)
{
int n;
for(n=0;n<32;n++){
printf("put->%d\n",n);
put(&buffer,n);
sleep(1);
}
put(&buffer,OVER);
printf("producer stopped! \n");
return NULL;
}
void *consumer(void *data)
{
int d;
while(1){
d=get(&buffer);
if(d==OVER) break;
printf("\t%d->get\n",d);
sleep(1);
}
printf("consumer stopped!\n");
return NULL;
}
/*---------------------------/*/
int main(void)
{
pthread_t th_a,th_b;
void *retval;
init(&buffer);
pthread_create(&th_a,NULL,producer,NULL);
pthread_create(&th_b,NULL,consumer,NULL);
/* 阻塞,等待建立的那两个线程的结束 */
pthread_join(th_a,&retval);
pthread_join(th_b,&retval);
return 0;
}
输出结果
put->0
0->get
put->1
1->get
put->2
2->get
put->3
3->get
put->4
4->get
put->5
5->get
put->6
6->get
put->7
7->get
put->8
8->get
put->9
9->get
put->10
10->get
put->11
11->get
put->12
12->get
put->13
13->get
put->14
14->get
put->15
15->get
put->16
16->get
put->17
17->get
put->18
18->get
put->19
19->get
put->20
20->get
put->21
21->get
put->22
22->get
put->23
23->get
put->24
24->get
put->25
25->get
put->26
26->get
put->27
27->get
put->28
28->get
put->29
29->get
put->30
30->get
put->31
31->get
producer stopped!
consumer stopped!
将sleep()注释掉的结果
wait for not empty
put->0
put->1
put->2
put->3
put->4
put->5
put->6
put->7
put->8
put->9
put->10
put->11
put->12
put->13
put->14
put->15
wait for not full
0->get
1->get
2->get
3->get
4->get
5->get
6->get
7->get
8->get
9->get
10->get
11->get
12->get
13->get
14->get
15->get
wait for not empty
put->16
put->17
put->18
put->19
put->20
put->21
put->22
put->23
put->24
put->25
put->26
put->27
put->28
put->29
put->30
put->31
16->get
wait for not full
17->get
18->get
19->get
20->get
21->get
22->get
23->get
24->get
25->get
26->get
27->get
28->get
29->get
30->get
31->get
consumer stopped!
producer stopped!