一、头文件 - semaphore.h
1> 信号量类型: sem_t sem; -- 加强版的互斥锁
2> 主要函数
1) 初始化信号量
sem_init(sem_t* sem, int pshared, unsigned int value);
pshated: 0 线程同步, 1 进程同步
value: 最多有几个线程操作共享数据
2) 销毁信号量
sem_destroy(sem_t* sem);
3) 加锁 --
sem_wait(sem_t* sem);
调用一次相当于对sem做了 -- 操作
如果sem值未0, 线程会阻塞
4) 尝试加锁
sem_trywait(sem_t* sem);
成功sem == 0,
加锁失败, 不阻塞, 直接返回
5) 限时尝试加锁
sem_timedwait(sem_t* sem, const struct timespec *abs_timeout);
如果加锁失败, 会在n秒内持续尝试加锁, 过时放弃加锁
6) 解锁 ++
sem_post(sem_t* sem);
对sem做了++操作
二、信号量实现生产者消费者模型
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <pthread.h>
#include <semaphore.h>
// Node
typedef struct Node {
int data;
struct Node* next;
}Node;
// Link
static Node* _head = NULL;
static int _id = 0;
static sem_t _product;
static sem_t _customer;
// 生产者
extern void* productor_func(void* arg);
// 消费者
extern void* customer_func(void* arg);
// 是否拥有库存
extern int store_isEmpty();
// 库存数量
extern int store_count();
// 创建节点
extern Node* create_node(int data);
// 添加节点
extern int insert_node(Node* node);
// 删除节点
extern Node* del_node();
// 打印链表
extern void print_store();
int main(int argc, char* argv[]) {
sem_init(&_product, 0, 4);
sem_init(&_customer, 0, 0);
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_t p[3];
pthread_create(p + 0, &attr, productor_func, NULL);
pthread_create(p + 1, &attr, customer_func, (void*)1);
pthread_create(p + 2, &attr, customer_func, (void*)2);
while(1);
sem_destroy(&_product);
sem_destroy(&_customer);
return 0;
}
// 生产者
void* productor_func(void* arg) {
while(1) {
sem_wait(&_product);
Node* node = create_node(_id++);
int ret = insert_node(node);
if(ret != 0) {
printf("insert node faild: ");
exit(1);
}
sem_post(&_customer);
sleep(rand() % 2 + 1);
}
return NULL;
}
// 消费者
void* customer_func(void* arg) {
int idx = (int)arg;
while(1) {
sem_wait(&_customer);
Node* ret = del_node();
if(ret == NULL) {
printf("del node faild: ");
exit(1);
}
printf("消费者%d: %d\n", idx, ret->data);
free(ret);
print_store();
sem_post(&_product);
sleep(rand() % 5 + 1);
}
return NULL;
}
/*******************************************/
// 是否拥有库存
int store_isEmpty() {
return _head == NULL ? 1 : 0;
}
// 库存数量
int store_count() {
int count = 0;
Node* node = _head;
while(node != NULL) {
count++;
node = node->next;
}
return count;
}
// 创建节点
Node* create_node(int data) {
Node* node = (Node*)malloc(sizeof(Node));
if (node == NULL) {
perror("create node error: ");
exit(1);
}
node->data = data;
node->next = NULL;
return node;
}
// 添加节点
int insert_node(Node* node) {
if (node == NULL) {
return -1;
}
if (_head == NULL) {
_head = node;
} else {
node->next = _head;
_head = node;
}
printf("生产: %d\n", _head->data);
return 0;
}
// 删除节点
Node* del_node() {
if(_head == NULL) {
return -1;
}
Node* out = _head;
if(out != NULL) {
Node* cur_node = _head->next;
_head = cur_node;
}
return out;
}
void print_store() {
printf("\nprint_begin\n");
if (_head == NULL) {
printf("\nprint_end\n");
return;
}
Node* cur_node = _head;
int i = 0;
while (cur_node != NULL) {
printf("%d\t", cur_node->data);
cur_node = cur_node->next;
i++;
}
printf("\nprint_end\n");
}
网友评论