1、信号量实现
#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>
#include <string.h>
struct msg
{
char buf[20]; // 缓冲区中的数据
sem_t full; // 控制消费者进入
sem_t empty; // 控制生产者进入
}data; // 全局数据
// 生产者工作函数
void *produce(void *v)
{
char *buf[] = {"苹果", "梨", "香蕉", "西瓜", "芒果", "葡萄", "菠萝", "红柚"};
int len = sizeof(buf)/sizeof(buf[0]);
while (1)
{
sem_wait(&data.empty); // 生产者只有当缓冲区为空的时候才能进入
usleep(100000*(rand()%10+1));
strcpy(data.buf, buf[rand()%len]);
sem_post(&data.full); // 生产者放入消息以后,通知消费者去处理
}
}
// 消费者工作函数
void *consume(void *v)
{
long num = (long)v;
while (1)
{
sem_wait(&data.full); // 消费者只有当缓冲区中有数据的时候才能进入
usleep(100000*(rand()%10+1));
printf ("%ld 号消费者,吃了一个 %s\n", num, data.buf);
data.buf[0] = '\0';
sem_post(&data.empty); // 消费者处理完数据以后,通知生产者去放数据
}
}
int main(int argc, char **argv)
{
srand((unsigned int)time(NULL));
long i;
pthread_t thread;
for (i = 0; i < 4; i++)
{
pthread_create(&thread, NULL, consume, (void*)(i+1));
pthread_detach(thread);
}
pthread_create(&thread, NULL, produce, NULL);
pthread_detach(thread);
sem_init(&data.full, 0, 0);
sem_init(&data.empty, 0, 1);
pthread_exit(NULL);
return 0;
}
2、信号量与互斥锁实现
#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>
#include <string.h>
struct msg
{
char *buf[10]; // 缓冲区中的数据
sem_t full; // 控制消费者进入
sem_t empty; // 控制生产者进入
int count; // 资源的个数
}data; // 全局数据
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 互斥锁
// 生产者工作函数
void *produce(void *v)
{
char *buf[] = {"苹果", "梨", "香蕉", "西瓜", "芒果", "葡萄", "菠萝", "红柚"};
int len = sizeof(buf)/sizeof(buf[0]);
while (1)
{
usleep(100000*(rand()%10+1));
sem_wait(&data.empty); // 生产者只有当缓冲区为空的时候才能进入
pthread_mutex_lock(&mutex);
data.buf[data.count] = buf[rand()%len];
data.count ++;
pthread_mutex_unlock(&mutex);
sem_post(&data.full); // 生产者放入消息以后,通知消费者去处理
}
}
// 消费者工作函数
void *consume(void *v)
{
long num = (long)v;
while (1)
{
usleep(100000*(rand()%10+1));
sem_wait(&data.full); // 消费者只有当缓冲区中有数据的时候才能进入
pthread_mutex_lock(&mutex);
int index = rand() % data.count;
printf ("%ld 号消费者,吃了一个 %s, 剩余个数:%d\n", num, data.buf[index], data.count-1);
data.count--;
char *tmp = data.buf[index];
data.buf[index] = data.buf[data.count];
data.buf[data.count] = tmp;
pthread_mutex_unlock(&mutex);
sem_post(&data.empty); // 消费者处理完数据以后,通知生产者去放数据
}
}
int main(int argc, char **argv)
{
srand((unsigned int)time(NULL));
long i;
pthread_t thread;
for (i = 0; i < 4; i++)
{
pthread_create(&thread, NULL, consume, (void*)(i+1));
pthread_detach(thread);
}
for (i = 0; i < 4; i++)
{
pthread_create(&thread, NULL, produce, NULL);
pthread_detach(thread);
}
sem_init(&data.full, 0, 0);
sem_init(&data.empty, 0, 10);
pthread_exit(NULL);
return 0;
}
3、互斥锁和条件变量实现
#include <stdio.h>
#include <semaphore.h>
#include <pthread.h>
#include <string.h>
struct msg
{
char *buf[10]; // 缓冲区中的数据
sem_t full; // 控制消费者进入
sem_t empty; // 控制生产者进入
int count; // 资源的个数
}data; // 全局数据
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 互斥锁
// 生产者工作函数
void *produce(void *v)
{
char *buf[] = {"苹果", "梨", "香蕉", "西瓜", "芒果", "葡萄", "菠萝", "红柚"};
int len = sizeof(buf)/sizeof(buf[0]);
while (1)
{
usleep(100000*(rand()%10+1));
sem_wait(&data.empty); // 生产者只有当缓冲区为空的时候才能进入
pthread_mutex_lock(&mutex);
data.buf[data.count] = buf[rand()%len];
data.count ++;
pthread_mutex_unlock(&mutex);
sem_post(&data.full); // 生产者放入消息以后,通知消费者去处理
}
}
// 消费者工作函数
void *consume(void *v)
{
long num = (long)v;
while (1)
{
usleep(100000*(rand()%10+1));
sem_wait(&data.full); // 消费者只有当缓冲区中有数据的时候才能进入
pthread_mutex_lock(&mutex);
int index = rand() % data.count;
printf ("%ld 号消费者,吃了一个 %s, 剩余个数:%d\n", num, data.buf[index], data.count-1);
data.count--;
char *tmp = data.buf[index];
data.buf[index] = data.buf[data.count];
data.buf[data.count] = tmp;
pthread_mutex_unlock(&mutex);
sem_post(&data.empty); // 消费者处理完数据以后,通知生产者去放数据
}
}
int main(int argc, char **argv)
{
srand((unsigned int)time(NULL));
long i;
pthread_t thread;
for (i = 0; i < 4; i++)
{
pthread_create(&thread, NULL, consume, (void*)(i+1));
pthread_detach(thread);
}
for (i = 0; i < 4; i++)
{
pthread_create(&thread, NULL, produce, NULL);
pthread_detach(thread);
}
sem_init(&data.full, 0, 0);
sem_init(&data.empty, 0, 10);
pthread_exit(NULL);
return 0;
}