수상 록 (linux 에서 pv 동작)

【 성명: 판권 소유, 전재 환영, 상업 용도 로 사용 하지 마 십시오.  연락처: feixiaoxixing @ 163. com]
      pv 작업 부분 에 관 한 내용 은 사실 새로운 것 이 라 고 할 수 없습니다.그러나 그것 은 우리 가 신 호 량, 메시지 처리 부분 을 이해 하 는 데 큰 도움 이 된다.이전에 우 리 는 win 32 의 처리 방안 을 제 시 했 지만 비교적 경솔하게 실현 되 었 다.그래서 우 리 는 오늘 Liux 의 신 호 량 함 수 를 이용 하여 이 기능 을 다시 실현 할 수 있다.
    (1) linux 아래 신 호 량 의 기본 함수
    a) 신 호 량 생 성  sem_init
    b) 대기 신 호 량 semwait
    c) 방출 신 호 량 sempos
    d) 신 호 량 삭제 semdestroy
    (2) pv 조작 함수 작성
    pv 작업 을 작성 할 때 메시지 처리 순서 문 제 를 고려 하지 않 았 기 때문에 극단 적 인 상황 에서 문제 가 생 길 수 있 습 니 다.그래서 이번 pv 작업 은 순환 대기 열의 형식 을 채택 하여 메시지 의 선후 입대 순 서 를 유지 하 였 다.이렇게 하면 라인 에서 받 은 각종 소식 을 순서대로 처리 하여 해결 할 수 있다.마찬가지 로 우리 파일 을 컴 파일 하 는 방법 은 매우 간단 합 니 다. 셸 에 gcc sem. c - g - o sem - lpthread 를 입력 하면 됩 니 다.
    단독 순환 대기 열과 pv 조작 처리 에 어떤 차이 가 있 느 냐 는 학생 들 의 질문 이 있 을 수 있 습 니 다.사실 차 이 는 매우 간단 합 니 다. pv 는 서로 다른 스 레 드 로 메 시 지 를 보 낼 수 있 고 순환 대기 열 은 하나의 스 레 드 로 보 내 는 메 시 지 를 받 아들 일 수 있 습 니 다. 그렇지 않 으 면 처리 가 번 거 롭 습 니 다.
#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
", index); index ++; sleep(1); } return NULL; } void* get_func(void* args) { int data; while(1) { get_msg(p_msg, &data); printf("get %d
", 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; }

좋은 웹페이지 즐겨찾기