自己写的alarm_cond

本文介绍了一个基于C语言的多线程定时器程序设计,该程序使用了标准的线程库来实现实时报警提醒功能。通过创建链表结构存储定时任务,并利用条件变量和互斥锁协调线程间的数据同步。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

#include<stdio.h>
#include"errors.h"
#include<pthread.h>
#include<time.h>
typedef struct alarm_tag{
int        seconds;
time_t     alarm_time;
char       message[64];
struct alarm_tag *link;
}alarm_t;
alarm_t *alarm_list=NULL;
pthread_mutex_t mutex =PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond_t=PTHREAD_COND_INITIALIZER;
time_t current_time=0;
void insert(alarm_t *alarm)
{
    int status;
     alarm_t **last, *next;

     last = &alarm_list;
     next = *last;
     while (next != NULL)
     {
         if (next->alarm_time >= alarm->alarm_time)
         {
             alarm->link = next;
             *last = alarm;
             break;
         }
         last = &next->link;
         next = next->link;
     }
     if (next == NULL) {
         *last = alarm;
         alarm->link = NULL;
     }

/*注意这里链表的插入方法,标准的链表插入中,需要分情况讨论,队头,队中,队尾,这里把队头和队中进行了合并,利用的是一个**last指针,这个指针在刚开始的时候保存的是队头的地址,如果不需要在队头插入,利用last=&next->link,可以保存下一个的节点的地址,找到合适的插入地址,让last指向alarm,alarm指向next即可。本质上和链表的插入方法是一样的,但是巧妙利用了指针。

刚才仔细考虑才知道自己一直存在的误区是链头指针不是元素,它是指向第一个元素的,每个元素都有一个指针指向它,那么只要让这个指向元素的指针链进行传递就可以了,这也就是上面的代码表示的含义。让last指向这个指针链,但是因为这个指针链有两个名字,alarm_list和next->link,所以找一个再找一个指针来指向它们,这就是**last。*/
if(current_time==0||current_time>alarm->alarm_time)
{
   current_time=alarm->alarm_time;
   status=pthread_cond_signal(&cond_t);
   if(status!=0)
    err_abort(status,"Signal cond");
}
}


void *alarm_wait(void *arg)
{
struct timespec cond_time;
alarm_t *alarm;
time_t now;
int status,expiration;

status=pthread_mutex_lock(&mutex);
if(status!=0)
   err_abort(status,"mutex lock");

while(1)
{
   current_time=0;
   while(alarm_list==NULL)
   {
   status=pthread_cond_wait(&cond_t,&mutex);
   if(status!=0)
     err_abort(status,"alarm wait");
   }
   alarm=alarm_list;
   alarm_list=alarm->link;//这一句保证了当前正在使用的闹铃已经不在队列当中
   now=time(NULL);
   cond_time.tv_sec=alarm->alarm_time;
   cond_time.tv_nsec=0;
   current_time=alarm->alarm_time;
   expiration=0;
   if(alarm->alarm_time>now)
   {
    while(current_time==alarm->alarm_time)
    {
     status=pthread_cond_timedwait(&cond_t,&mutex,&cond_time);
     if(status==ETIMEDOUT)
     {
      expiration=1;
      break;
     }
    if(status!=0)
      err_abort(status,"alarm waittime");
    }
   if(!expiration)
    insert(alarm);
   }
   else expiration=1;
   if(expiration)
   {
    printf("%d,%s/n",alarm->seconds,alarm->message);
    free(alarm);//释放空间
   }
}
}
int main(){
pthread_t wait;
alarm_t *new_alarm;
int status;

status = pthread_create(&wait,NULL,alarm_wait,NULL);
if(status!=0)
   err_abort(status,"create alarm thread");
while(1)
{
   printf ("Alarm> ");
   new_alarm=(alarm_t*)malloc(sizeof(alarm_t));
   scanf("%d %s",&new_alarm->seconds,new_alarm->message);//直接scanf也是可以的,当然这里没有原程序的纠错机制,可以另外加上

   new_alarm->alarm_time=time(NULL)+new_alarm->seconds;
   status=pthread_mutex_lock(&mutex);//这里的操作是必须的,保证两个线程对链表的操作是互斥的,以防止插入元素过程中,等待线程启动,造成不可知的后果
   if(status!=0)
     err_abort(status,"mutex lock");
   insert(new_alarm);
   status=pthread_mutex_unlock(&mutex);
   if(status!=0)
     err_abort(status,"mutex unlock");
}
}

<select id="selectPageWithParam" resultType="com.cmb.xft.ini.domain.pojo.InvoiceRiskAlarmResult"> select ira.id as id, ira.enterprise_id as enterprise_id, ira.alarm_date as alarm_date, ira.invoice_in_id as invoice_in_id, ira.alarm_info as alarm_info, i.invoice_code as invoice_code, i.invoice_number as invoice_number, i.electronic_invoice_number as electronic_invoice_number, i.issue_time as issue_time, i.invoice_type as invoice_type, i.sys_invoice_type as sys_invoice_type, i.invoice_status as invoice_status, i.buyer_company_name as buyer_company_name, i.buyer_taxpayer_id as buyer_taxpayer_id, i.seller_company_name as seller_company_name, i.seller_taxpayer_id as seller_taxpayer_id, i.tax_included_amount as tax_included_amount from invoice_in_risk_alarm ira left join invoice_in i on ira.invoice_in_id = i.id where ira.enterprise_id = #{enterpriseId} <if test="param.newestAlarmDateStart != null"> and ira.alarm_date >= #{param.newestAlarmDateStart} </if> <if test="param.newestAlarmDateEnd != null"> and ira.alarm_date <= #{param.newestAlarmDateEnd} </if> <if test="param.alarmInfo != null and param.alarmInfo.size() != 0"> and <foreach collection="param.alarmInfo" item="alarmInfo" open="(" separator="or" close=")"> ira.alarm_info like concat('%', #{alarmInfo}, '%') </foreach> </if> <if test="param.sysInvoiceTypes != null and param.sysInvoiceTypes.size() != 0"> and i.sys_invoice_type in <foreach collection="param.sysInvoiceTypes" item="invoiceType" open="(" separator="," close=")"> #{invoiceType} </foreach> </if> <if test="param.invoiceStatuses != null and param.invoiceStatuses.size() != 0"> and i.invoice_status in <foreach collection="param.invoiceStatuses" item="invoiceStatus" open="(" separator="," close=")"> #{invoiceStatus} </foreach> </if> <if test="param.sellerTaxpayerId != null and param.sellerTaxpayerId != ''"> and i.seller_taxpayer_id like concat('%', #{param.sellerTaxpayerId}, '%') </if> <if test="param.sellerCompanyName != null and param.sellerCompanyName != ''"> and i.seller_company_name like concat('%', #{param.sellerCompanyName}, '%') </if> <if test="param.invoiceNumber != null and param.invoiceNumber != ''"> and i.invoice_number like concat('%', #{param.invoiceNumber}, '%') </if> <if test="param.invoiceCodePattern != null and param.invoiceCodePattern != ''"> and i.invoice_code like concat('%', #{param.invoiceCodePattern}, '%') </if> <if test="param.electronicInvoiceNumber != null and param.electronicInvoiceNumber != ''"> and i.electronic_invoice_number like concat('%', #{param.electronicInvoiceNumber}, '%') </if> <if test="param.issueTimeStart != null"> and i.issue_time >= #{param.issueTimeStart} </if> <if test="param.issueTimeEnd != null"> and i.issue_time < #{param.issueTimeEnd} </if> <if test="param.taxIncludedAmountStart != null"> and i.tax_included_amount >= #{param.taxIncludedAmountStart} </if> <if test="param.taxIncludedAmountTo != null"> and i.tax_included_amount <= #{param.taxIncludedAmountTo} </if> <choose> <when test="param.orderQueryParam != null"> order by <if test="param.orderQueryParam.field != null and param.orderQueryParam.field != ''"> ${param.orderQueryParam.field} ${param.orderQueryParam.method}, </if> ira.update_time desc </when> <otherwise> order by ira.update_time desc, i.invoice_number desc </otherwise> </choose> </select> 这一段有什么错误吗
06-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值