链表+POSIX信号量+条件变量实现的闹铃V1

来源:互联网 发布:淘宝 日语 编辑:程序博客网 时间:2024/05/16 17:00
<span style="font-family:Courier New;font-size:18px;">#include <stdio.h>#include <stdlib.h>#include <time.h>#include <pthread.h>#include <string.h>#include <unistd.h>typedef struct alarm_list_tag{time_t time;char msg[64];int seconds;struct alarm_list_tag *next;}alarm_list_t;typedef alarm_list_t alarm_list_elem_t;alarm_list_t *alarm_list = NULL;pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t cond = PTHREAD_COND_INITIALIZER;alarm_list_elem_t *AllocElem(time_t time, int seconds, char *msg){if(strlen(msg) > 64){fprintf(stderr, "msg too long\n");return NULL;}alarm_list_elem_t *tmp = (alarm_list_elem_t *)malloc(sizeof(alarm_list_elem_t));{//}tmp->time = time;tmp->seconds = seconds;memcpy(tmp->msg, msg, strlen(msg));tmp->next = NULL;return tmp;}int FindDuplicate(alarm_list_t *l, int key){alarm_list_t *p = NULL;int isFound = 0;for( p=l; p!=NULL; p=p->next){if( p->time == key ){isFound = 1;break;}}return isFound;}//in ascending order//no duplicate elementalarm_list_t *Insert(alarm_list_t *l, alarm_list_elem_t *elem){//find duplicateif( FindDuplicate(l, elem->time) ){fprintf(stderr, "already have same timer! time = %ld, seconds = %d\n", elem->time, elem->seconds);return l;}//empty listif( l == NULL ){//fprintf(stderr, "alarm_list: empty list\n");return elem;}//new < headerif( l->time > elem->time ){//fprintf(stderr, "alarm_list: new < header\n");elem->next = l;return elem;}//header < new and list lenth is 1if(l->next == NULL){//fprintf(stderr, "alarm_list: header < new elem && len 1\n");l->next = elem;return l;}//header < new elem && len > 1{//fprintf(stderr, "alarm_list: header < new elem && len > 1\n");alarm_list_t *prev = l;alarm_list_t *p = prev->next;for(; p != NULL; p = p->next){if(prev->time < elem->time && p->time > elem->time){prev->next = elem;elem->next = p;//fprintf(stderr, "case 1\n");return l;}else if(prev->time < elem->time && p->time < elem->time){prev = p;}else{fprintf(stderr, "duplicate \n");}}//we reach the end of listif( p ==NULL ){prev->next = elem;}return l;}}alarm_list_elem_t *PopList(alarm_list_t **l){if(*l == NULL){//fprintf(stderr, "empty list\n");return NULL;}//fprintf(stderr, "pop elem %d, addr = %p\n", (*l)->seconds, *l);alarm_list_elem_t *tmp = *l;*l = (*l)->next;tmp->next = NULL;return tmp;}void Popfront(alarm_list_t **l){if(*l == NULL){//fprintf(stderr, "empty list\n");return;}alarm_list_elem_t *tmp = *l;(*l) = (*l)->next;free(tmp);}void PrintList(alarm_list_t *l){for(; l != NULL; l=l->next){fprintf(stderr, "Print:time = %ld, seconds = %d, message = %s\n", l->time, l->seconds, l->msg);}}//0.5s#define SLEEP_TIME (1000000000/2)void *alarm_thread(void *arg){while(1){pthread_mutex_lock(&mutex);if(alarm_list == NULL){pthread_cond_wait(&cond, &mutex);}if(alarm_list != NULL){time_t now = time(NULL);if( now == alarm_list->time ){fprintf(stderr, "alarm!!!time = %ld, seconds = %d, msg = %s\n", alarm_list->time, alarm_list->seconds, alarm_list->msg);Popfront(&alarm_list);}else{struct timespec to;to.tv_sec = time(NULL);to.tv_nsec = SLEEP_TIME;pthread_cond_timedwait(&cond, &mutex, &to);}}pthread_mutex_unlock(&mutex);}}int main(){pthread_t alarm_pid;pthread_create(&alarm_pid, NULL, &alarm_thread, NULL);int seconds[] = { 15, 16, 25, 23, 7, 14, 28, 39, 100, 20};char msg[64] = "asd";time_t now;int i = 0;while(1){//scanf("%d%s", &seconds, msg);sleep(2);now = time(NULL);alarm_list_elem_t *elem = AllocElem(now+seconds[i], seconds[i], msg);if(elem == NULL){fprintf(stderr, "");}pthread_mutex_lock(&mutex);alarm_list = Insert(alarm_list, elem);pthread_mutex_unlock(&mutex);//we didnot wake up the alarm_thread immediately until we release the lockpthread_cond_signal(&cond);i++;if(i == 10){break;}}pthread_join(alarm_pid, NULL);}</span>

0 0