#include <stdio.h> #include <malloc.h> #include <string.h> #include <pthread.h> #include <semaphore.h> struct MSG { sem_t s_empty; sem_t s_full; sem_t s_msg; int* p_buffer; int start; int end; int count; }; #define STATUS int #define TRUE 1 #define FALSE 0 static struct MSG* p_msg = NULL;
struct MSG* alloc_msg(int count) { struct MSG* p_msg; p_msg = (struct MSG*) malloc(sizeof(struct MSG)); if(NULL == p_msg) { goto error1; } memset(p_msg, 0, sizeof(struct MSG)); p_msg->count = count;
p_msg->p_buffer = (int*)malloc(sizeof(int)* count); if(NULL == p_msg->p_buffer) { goto error2; } sem_init(&p_msg->s_empty, 0, count); sem_init(&p_msg->s_full, 0, 0); sem_init(&p_msg->s_msg, 0, 1); return p_msg; error2: free(p_msg); error1: return; } void del_msg(struct MSG* p_msg) { if(p_msg) { if(p_msg->p_buffer) { free(p_msg->p_buffer); } sem_destroy(&p_msg->s_msg); sem_destroy(&p_msg->s_full); sem_destroy(&p_msg->s_empty); free(p_msg); } }
STATUS put_msg(struct MSG* p_msg, int data) { if(NULL == p_msg ) { return FALSE; }
sem_wait(&p_msg->s_empty); sem_wait(&p_msg->s_msg); p_msg->p_buffer[p_msg->start] = data; p_msg->start = (p_msg->start + 1) % p_msg->count; sem_post(&p_msg->s_msg); sem_post(&p_msg->s_full); return TRUE; } STATUS get_msg(struct MSG* p_msg, int* p_buf) { if(NULL == p_msg || NULL == p_buf) { return FALSE; }
sem_wait(&p_msg->s_full); sem_wait(&p_msg->s_msg); p_buf[0] = p_msg->p_buffer[p_msg->end]; p_msg->end = (p_msg->end + 1)% p_msg->count; sem_post(&p_msg->s_msg); sem_post(&p_msg->s_empty); return TRUE; } void* set_func(void* args) { int index = 100; while(1) { put_msg(p_msg, index); printf("set %d\n", index); index ++; sleep(1); }
return NULL; } void* get_func(void* args) { int data;
while(1) { get_msg(p_msg, &data); printf("get %d\n", data); sleep(1); } return NULL; } int main(int argc, char* argv[]) { pthread_t pid1, pid2; int index;
p_msg = alloc_msg(10); if(NULL == p_msg) { goto end; } if(pthread_create(&pid1, NULL, set_func, NULL)) { goto end; } if(pthread_create(&pid2, NULL, get_func, NULL)) { goto end; } while(1) { sleep(0); } end: return 1; } |