使用Linux平台的pthread库进行多线程编程实现生产者消费者问题。
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#define P sem_wait
#define V sem_post
sem_t empty;
sem_t full;
pthread_mutex_t mutex;
int val = 0;
void *provider(){
while (1)
{
P(&empty);
pthread_mutex_lock(&mutex);
val++;
printf("provider: provide one good!/now have %d\n",val);
pthread_mutex_unlock(&mutex);
V(&full);
sleep(3);
}
}
void *consumer(){
while (1)
{
P(&full);
pthread_mutex_lock(&mutex);
val--;
printf("consumer: consume one good!/now have %d\n",val);
pthread_mutex_unlock(&mutex);
V(&empty);
sleep(1);
}
}
int main(int argc, char const *argv[])
{
pthread_mutex_init(&mutex,NULL);
sem_init(&empty,0,20);
sem_init(&full,0,0);
pthread_t t1;
pthread_t t2;
pthread_create(&t1,NULL,provider,NULL);
pthread_create(&t1,NULL,consumer,NULL);
pthread_join(t1,NULL); // wiat t1 end
pthread_join(t2,NULL); // wait t2 end
pthread_mutex_destroy(&mutex);
return 0;
}
定义了两个信号量full,empty和一个互斥变量mutex。其中full和empty用于实现同步,mutex用于实现互斥访问val进行存取(即改变val的值)。
由main方法中的**sem_init(&empty,0,20)**可以看出val的取值范围为[0-20],程序开始时初始化val值为0,full为0,empty为20。然后起t1,t2两个线程分别为生产者和消费者线程。
- 生产者线程主要是先申请(P)一个empty的空间然后互斥访问val进行生产(即val++)生产完成后释放(V)full表示val中已经有一个生产完成的资源了。
- 消费者线程主要是先申请(P)一个full的空间然后互斥访问val进行消费(即val–)消费完成后释放(V)empty表示val中已经有一个资源被消费了。
由于消费者线程中sleep(3);而生产者线程中为slee(1);
所以执行结果为:
michael@DESKTOP-6N96H5I:/mnt/e/test$ gcc threadTest.c -lpthread && ./a.out
provider: provide one good!/now have 1
consumer: consume one good!/now have 0
provider: provide one good!/now have 1
consumer: consume one good!/now have 0
provider: provide one good!/now have 1
consumer: consume one good!/now have 0
provider: provide one good!/now have 1
consumer: consume one good!/now have 0
provider: provide one good!/now have 1
consumer: consume one good!/now have 0
provider: provide one good!/now have 1
consumer: consume one good!/now have 0
如果将其对调即消费者线程中sleep(1);而生产者线程中为slee(3);则执行结果为:
michael@DESKTOP-6N96H5I:/mnt/e/test$ gcc threadTest.c -lpthread && ./a.out
provider: provide one good!/now have 1
consumer: consume one good!/now have 0
provider: provide one good!/now have 1
provider: provide one good!/now have 2
consumer: consume one good!/now have 1
provider: provide one good!/now have 2
provider: provide one good!/now have 3
provider: provide one good!/now have 4
consumer: consume one good!/now have 3
provider: provide one good!/now have 4
provider: provide one good!/now have 5
provider: provide one good!/now have 6
consumer: consume one good!/now have 5
provider: provide one good!/now have 6
provider: provide one good!/now have 7
provider: provide one good!/now have 8
consumer: consume one good!/now have 7
provider: provide one good!/now have 8
provider: provide one good!/now have 9
provider: provide one good!/now have 10
consumer: consume one good!/now have 9
provider: provide one good!/now have 10
provider: provide one good!/now have 11
provider: provide one good!/now have 12
consumer: consume one good!/now have 11
provider: provide one good!/now have 12
provider: provide one good!/now have 13
provider: provide one good!/now have 14
consumer: consume one good!/now have 13
provider: provide one good!/now have 14
provider: provide one good!/now have 15
provider: provide one good!/now have 16
consumer: consume one good!/now have 15
provider: provide one good!/now have 16
provider: provide one good!/now have 17
provider: provide one good!/now have 18
consumer: consume one good!/now have 17
provider: provide one good!/now have 18
provider: provide one good!/now have 19
provider: provide one good!/now have 20
consumer: consume one good!/now have 19
provider: provide one good!/now have 20
consumer: consume one good!/now have 19
provider: provide one good!/now have 20
P.s.其实mutex也可以用semphore来定义即
sem_t mutex;
sem_init(&mutex,0,1);
这样PV操作更加统一!