线程互斥锁的问题(线程中使用定时器信号)

来源:互联网 发布:南通水立方js漂亮吗 编辑:程序博客网 时间:2024/05/22 05:15

前一天利用apue的一个程序来实现一个小功能,主要是一个线程一秒钟采集一次数据。我想到用定时器来实现结合alarm函数。实现的代码如下:

#include <sys/types.h>         #include <sys/stat.h>#include <sys/termios.h>       #include <sys/ioctl.h>#include <sys/time.h>#include <sys/ipc.h>          #include <sys/msg.h>         #include <sys/sem.h>        #include <sys/shm.h>         #include <signal.h>                   #include <stdio.h>              #include <stdlib.h>             #include <stddef.h>             #include <string.h>        #include <math.h>#include <unistd.h>             #include <utmp.h>              #include <time.h>               #include <fcntl.h>#include <errno.h>#include <pthread.h>intquitflag;sigset_tmask;int hight,flightgate,Undercarriage,status;pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t waitloc = PTHREAD_COND_INITIALIZER;void switchmode(){switch(status){case 0 :              printf("insmod 3G.ko\n"); printf("insmod Wifi.ko\n"); break;    case 1 : printf("rmmod 3G.ko\n");                 printf("rmmod Wifi.ko\n"); break;            case  2: printf("insmod eth.ko\n"); printf("insmod Wifi.ko\n"); break;   default : break;}}void AT_429_data(){ //add comand here printf("please input data:\n");scanf("%d%d%d",&hight,&flightgate,&Undercarriage);if(flightgate==1&&Undercarriage==1){ //gate open equel 1;close equel 0.the same to Undercarriagestatus=0; //online state        printf("gate open ,Undercarriage open\n");    }if(flightgate==0||Undercarriage==0){ //gate close,Undercarriage closestatus=1;printf("gate close Undercarriage close\n");}if(hight>=3000){status=2;printf("Use Satellite\n");}switchmode();}void *thr_fn(void *arg){int err, signo;for (;;) {alarm(1);printf("waiting for signal.......\n");err = sigwait(&mask, &signo);if (err != 0)printf("sigwait failed\n");switch (signo) {case SIGALRM:AT_429_data();break;case SIGQUIT:pthread_mutex_lock(&lock);quitflag = 1;pthread_mutex_unlock(&lock);pthread_cond_signal(&waitloc);return(0);default:printf("unexpected signal %d\n", signo);exit(1);}}}void time_val(void){struct itimerval val; val.it_value.tv_sec = 1;val.it_value.tv_usec = 0;val.it_interval = val.it_value;setitimer(ITIMER_PROF, &val, NULL);} int  main(void){interr;sigset_toldmask;pthread_ttid;sigemptyset(&mask);sigaddset(&mask, SIGQUIT);//sigaddset(&mask,SIGPROF);sigaddset(&mask,SIGALRM);//time_val();if ((err = pthread_sigmask(SIG_BLOCK, &mask, &oldmask)) != 0)printf("SIG_BLOCK error");err = pthread_create(&tid, NULL, thr_fn, 0);if (err != 0)printf( "can't create thread\n");pthread_mutex_lock(&lock);while (quitflag == 0)pthread_cond_wait(&waitloc,&lock);pthread_mutex_unlock(&lock);quitflag = 0;if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)printf("SIG_SETMASK error\n");  exit(0); }
下面对程序做一说明,主函数中利用信号处理函数将SIGQUIT与SIGALARM信号添加到信号集中。再利用pthread_sigmask函数阻塞信号集中的所有信号。

然后创建子线程,在子线程的起始函数中,sigwait取消对信号集中所有信号的阻塞,并等待信号的到来。

主线程中加入互斥锁,进入休眠状态,利用pthread_cond_wait等待唤醒条件,一旦有唤醒条件,主线程将再次启动。

在子线程中,死循环中alarm函数每隔一秒产生一个SIGALARM信号,然后启动数据处理函数。直到摁下Ctrl+\后产生SIGQUIT信号,加锁设置退出标记位,利用pthread_cond_signal唤醒主线程。


0 0
原创粉丝点击