linux多线程编程(C):信号量实现的线程安全队列
2013-02-24 22:41
344 查看
用信号量实现的线程安全队列。
简单有用的示例程序,
比起互斥量的实现在多线程时效率更好。
cir_queue.h
/*
* \File
* cir_queue.h
* \Brief
* circular queue
*/
#ifndef __CIR_QUEUE_H__
#define __CIR_QUEUE_H__
#define QUE_SIZE 8
typedef int DataType;
typedef struct cir_queue_t
{
DataType data[QUE_SIZE];
int front;
int rear;
int count;
}cir_queue_t;
extern sem_t queue_sem;
void init_cir_queue(cir_queue_t* q);
int is_empty_cir_queue(cir_queue_t* q);
int is_full_cir_queue(cir_queue_t* q);
void push_cir_queue(cir_queue_t* q, DataType x);
DataType pop_cir_queue(cir_queue_t* q);
DataType top_cir_queue(cir_queue_t* q);
void destroy_cir_queue(cir_queue_t* q);
void print_queue(cir_queue_t* q);
#endif
main.c
/*
* \File
* main.c
* \Breif
* Thread-safe circular-queue implemented by semaphore
* \Author
* Hank.yan
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
#include "cir_queue.h"
void* thread_queue(void *arg);
/*
* \Func
* main
*/
int main(int argc, char* argv[])
{
int res;
cir_queue_t cq;
DataType e;
pthread_t a_thread, b_thread;
void* thread_result;
init_cir_queue(&cq);
push_cir_queue(&cq, 1);
push_cir_queue(&cq, 2);
push_cir_queue(&cq, 3);
print_queue(&cq);
res = pthread_create(&a_thread, NULL, thread_queue, (void*)&cq);
if (res != 0)
{
perror("Thread creation failed.");
exit(EXIT_FAILURE);
}
e = pop_cir_queue(&cq);
e = pop_cir_queue(&cq);
print_queue(&cq);
push_cir_queue(&cq, 9);
push_cir_queue(&cq, 100);
print_queue(&cq);
res = pthread_create(&b_thread, NULL, thread_queue, (void*)&cq);
if (res != 0)
{
perror("Thread creation failed.");
exit(EXIT_FAILURE);
}
e = pop_cir_queue(&cq);
push_cir_queue(&cq, 20);
print_queue(&cq);
printf("Waiting for thread to finish...\n");
res = pthread_join(a_thread, &thread_result);
if (res != 0)
{
perror("Thread join failed.");
exit(EXIT_FAILURE);
}
print_queue(&cq);
printf("Waiting for thread to finish...\n");
res = pthread_join(b_thread, &thread_result);
if (res != 0)
{
perror("Thread join failed.");
exit(EXIT_FAILURE);
}
destroy_cir_queue(&cq);
printf("Thread joined, it returned %s\n", (char*)thread_result);
exit(EXIT_SUCCESS);
}
void *thread_queue(void *cirqueue)
{
int flag;
DataType element;
print_queue((cir_queue_t*)cirqueue);
flag = is_empty_cir_queue((cir_queue_t*)cirqueue);
print_queue((cir_queue_t*)cirqueue);
element = pop_cir_queue((cir_queue_t*)cirqueue);
element = pop_cir_queue((cir_queue_t*)cirqueue);
print_queue((cir_queue_t*)cirqueue);
push_cir_queue((cir_queue_t*)cirqueue, 5);
print_queue((cir_queue_t*)cirqueue);
push_cir_queue((cir_queue_t*)cirqueue, 99);
push_cir_queue((cir_queue_t*)cirqueue, 1000);
push_cir_queue((cir_queue_t*)cirqueue, 88);
print_queue((cir_queue_t*)cirqueue);
pthread_exit("Thank you for the cpu time.");
}
cir_queue.c
/*
* \File
* cir_queue.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
#include "cir_queue.h"
sem_t queue_sem;
/*
* \Func
*
*/
void init_cir_queue(cir_queue_t *q)
{
int res;
/* Create semaphore */
res = sem_init(&queue_sem, 0, QUE_SIZE);
if (res != 0)
{
perror("Semaphore init failed.\n");
exit(EXIT_FAILURE);
}
memset(q->data, 0, QUE_SIZE*sizeof(DataType));
q->front = q->rear = 0;
q->count = 0;
}
/*
* \Func
*
*/
int is_empty_cir_queue(cir_queue_t *q)
{
int empty_flag;
sem_wait(&queue_sem);
empty_flag = q->front == q->rear;
sem_post(&queue_sem);
return empty_flag;
}
/*
* \Func
*
*/
int is_full_cir_queue(cir_queue_t *q)
{
int full_flag;
sem_wait(&queue_sem);
full_flag = q->rear == QUE_SIZE - 1 + q->front;
sem_post(&queue_sem);
return full_flag;
}
/*
* \Func
*
*/
void push_cir_queue(cir_queue_t *q, DataType x)
{
if (is_full_cir_queue(q))
{
printf("queue overflow.\n");
return ;
}
sem_wait(&queue_sem);
q->count++;
q->data[q->rear] = x;
q->rear = (q->rear+1) % QUE_SIZE;
sem_post(&queue_sem);
}
/*
* \Func
*
*/
DataType pop_cir_queue(cir_queue_t *q)
{
DataType temp;
if (is_empty_cir_queue(q))
{
printf("queue empty.\n");
return 0;
}
sem_wait(&queue_sem);
temp = q->data[q->front];
q->data[q->front] = 0;
q->count--;
q->front = (q->front+1) % QUE_SIZE;
sem_post(&queue_sem);
return temp;
}
/*
* \Func
*
*/
DataType top_cir_queue(cir_queue_t *q)
{
DataType x;
if (is_empty_cir_queue(q))
{
printf("queue is empty.\n");
return 0;
}
sem_wait(&queue_sem);
x = q->data[q->front];
sem_post(&queue_sem);
return x;
}
void destroy_cir_queue(cir_queue_t *q)
{
sem_destroy(&queue_sem);
return;
}
void print_queue(cir_queue_t* q)
{
int index;
if (is_empty_cir_queue(q))
{
printf("queue is empty.\n");
return;
}
sem_wait(&queue_sem);
printf("QUEUE: ");
for (index = 0; index < QUE_SIZE; index++)
{
printf(" %d ", q->data[index]);
}
printf("\n");
sem_post(&queue_sem);
return;
}
makefile
OBJECTS = main.o cir_queue.o
CC = gcc
CFLAGS = -D_REENTRANT -lpthread -g -Wall
thrd_safe_queue: $(OBJECTS)
$(CC) $(CFLAGS) -o
thrd_safe_queue $(OBJECTS)
main.o: cir_queue.h
cir_queue.o: cir_queue.h
.PHONY:clean
clean:
rm thrd_safe_queue $(OBJECTS)
简单有用的示例程序,
比起互斥量的实现在多线程时效率更好。
cir_queue.h
/*
* \File
* cir_queue.h
* \Brief
* circular queue
*/
#ifndef __CIR_QUEUE_H__
#define __CIR_QUEUE_H__
#define QUE_SIZE 8
typedef int DataType;
typedef struct cir_queue_t
{
DataType data[QUE_SIZE];
int front;
int rear;
int count;
}cir_queue_t;
extern sem_t queue_sem;
void init_cir_queue(cir_queue_t* q);
int is_empty_cir_queue(cir_queue_t* q);
int is_full_cir_queue(cir_queue_t* q);
void push_cir_queue(cir_queue_t* q, DataType x);
DataType pop_cir_queue(cir_queue_t* q);
DataType top_cir_queue(cir_queue_t* q);
void destroy_cir_queue(cir_queue_t* q);
void print_queue(cir_queue_t* q);
#endif
main.c
/*
* \File
* main.c
* \Breif
* Thread-safe circular-queue implemented by semaphore
* \Author
* Hank.yan
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
#include "cir_queue.h"
void* thread_queue(void *arg);
/*
* \Func
* main
*/
int main(int argc, char* argv[])
{
int res;
cir_queue_t cq;
DataType e;
pthread_t a_thread, b_thread;
void* thread_result;
init_cir_queue(&cq);
push_cir_queue(&cq, 1);
push_cir_queue(&cq, 2);
push_cir_queue(&cq, 3);
print_queue(&cq);
res = pthread_create(&a_thread, NULL, thread_queue, (void*)&cq);
if (res != 0)
{
perror("Thread creation failed.");
exit(EXIT_FAILURE);
}
e = pop_cir_queue(&cq);
e = pop_cir_queue(&cq);
print_queue(&cq);
push_cir_queue(&cq, 9);
push_cir_queue(&cq, 100);
print_queue(&cq);
res = pthread_create(&b_thread, NULL, thread_queue, (void*)&cq);
if (res != 0)
{
perror("Thread creation failed.");
exit(EXIT_FAILURE);
}
e = pop_cir_queue(&cq);
push_cir_queue(&cq, 20);
print_queue(&cq);
printf("Waiting for thread to finish...\n");
res = pthread_join(a_thread, &thread_result);
if (res != 0)
{
perror("Thread join failed.");
exit(EXIT_FAILURE);
}
print_queue(&cq);
printf("Waiting for thread to finish...\n");
res = pthread_join(b_thread, &thread_result);
if (res != 0)
{
perror("Thread join failed.");
exit(EXIT_FAILURE);
}
destroy_cir_queue(&cq);
printf("Thread joined, it returned %s\n", (char*)thread_result);
exit(EXIT_SUCCESS);
}
void *thread_queue(void *cirqueue)
{
int flag;
DataType element;
print_queue((cir_queue_t*)cirqueue);
flag = is_empty_cir_queue((cir_queue_t*)cirqueue);
print_queue((cir_queue_t*)cirqueue);
element = pop_cir_queue((cir_queue_t*)cirqueue);
element = pop_cir_queue((cir_queue_t*)cirqueue);
print_queue((cir_queue_t*)cirqueue);
push_cir_queue((cir_queue_t*)cirqueue, 5);
print_queue((cir_queue_t*)cirqueue);
push_cir_queue((cir_queue_t*)cirqueue, 99);
push_cir_queue((cir_queue_t*)cirqueue, 1000);
push_cir_queue((cir_queue_t*)cirqueue, 88);
print_queue((cir_queue_t*)cirqueue);
pthread_exit("Thank you for the cpu time.");
}
cir_queue.c
/*
* \File
* cir_queue.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
#include "cir_queue.h"
sem_t queue_sem;
/*
* \Func
*
*/
void init_cir_queue(cir_queue_t *q)
{
int res;
/* Create semaphore */
res = sem_init(&queue_sem, 0, QUE_SIZE);
if (res != 0)
{
perror("Semaphore init failed.\n");
exit(EXIT_FAILURE);
}
memset(q->data, 0, QUE_SIZE*sizeof(DataType));
q->front = q->rear = 0;
q->count = 0;
}
/*
* \Func
*
*/
int is_empty_cir_queue(cir_queue_t *q)
{
int empty_flag;
sem_wait(&queue_sem);
empty_flag = q->front == q->rear;
sem_post(&queue_sem);
return empty_flag;
}
/*
* \Func
*
*/
int is_full_cir_queue(cir_queue_t *q)
{
int full_flag;
sem_wait(&queue_sem);
full_flag = q->rear == QUE_SIZE - 1 + q->front;
sem_post(&queue_sem);
return full_flag;
}
/*
* \Func
*
*/
void push_cir_queue(cir_queue_t *q, DataType x)
{
if (is_full_cir_queue(q))
{
printf("queue overflow.\n");
return ;
}
sem_wait(&queue_sem);
q->count++;
q->data[q->rear] = x;
q->rear = (q->rear+1) % QUE_SIZE;
sem_post(&queue_sem);
}
/*
* \Func
*
*/
DataType pop_cir_queue(cir_queue_t *q)
{
DataType temp;
if (is_empty_cir_queue(q))
{
printf("queue empty.\n");
return 0;
}
sem_wait(&queue_sem);
temp = q->data[q->front];
q->data[q->front] = 0;
q->count--;
q->front = (q->front+1) % QUE_SIZE;
sem_post(&queue_sem);
return temp;
}
/*
* \Func
*
*/
DataType top_cir_queue(cir_queue_t *q)
{
DataType x;
if (is_empty_cir_queue(q))
{
printf("queue is empty.\n");
return 0;
}
sem_wait(&queue_sem);
x = q->data[q->front];
sem_post(&queue_sem);
return x;
}
void destroy_cir_queue(cir_queue_t *q)
{
sem_destroy(&queue_sem);
return;
}
void print_queue(cir_queue_t* q)
{
int index;
if (is_empty_cir_queue(q))
{
printf("queue is empty.\n");
return;
}
sem_wait(&queue_sem);
printf("QUEUE: ");
for (index = 0; index < QUE_SIZE; index++)
{
printf(" %d ", q->data[index]);
}
printf("\n");
sem_post(&queue_sem);
return;
}
makefile
OBJECTS = main.o cir_queue.o
CC = gcc
CFLAGS = -D_REENTRANT -lpthread -g -Wall
thrd_safe_queue: $(OBJECTS)
$(CC) $(CFLAGS) -o
thrd_safe_queue $(OBJECTS)
main.o: cir_queue.h
cir_queue.o: cir_queue.h
.PHONY:clean
clean:
rm thrd_safe_queue $(OBJECTS)
相关文章推荐
- Linux多线程系列-2-条件变量的使用(线程安全队列的实现)
- Linux多线程系列-2-条件变量的使用(线程安全队列的实现)
- 【Linux】 多线程编程(信号量实现同步)
- linux下的多进程通信(IPC)原理及实现方案(管道、队列、信号量、共享内存)
- Linux通信机制(2)消息队列和信号量
- 实现信号量(三) 消息队列实现信号量
- Linux下用信号量实现对共享内存的访问保护(一)
- Linux下进程间通信方式之管道、信号、共享内存、消息队列、信号量、套接字
- Linux2.6中断下半部分的三种实现机制---工作队列 .
- Linux RCU队列(1)经典RCU队列实现
- Linux工作队列实现机制
- Linux进程间通信--进程,信号,管道,消息队列,信号量,共享内存
- [linux,c++] 基于mutex 的互斥访问队列实现
- Linux内核通用队列的使用笔记(读linux内核设计与实现)
- Linux信号量的实现(笔记)
- Linux Programing -- ch14-- 信号量、共享内存、消息队列
- linux多线程学习(六)——信号量实现同步。
- Linux平台用C++实现信号量,同步线程
- linux 队列 C实现
- 【LINUX/UNIX网络编程】之使用消息队列,信号量和命名管道实现的多进程服务器(多人群聊系统)