关于多线程、安装信号、长跳转、数据结构等的例子

来源:互联网 发布:mysql数据库表设计 编辑:程序博客网 时间:2024/06/06 20:09
#include <stdio.h>#include <stdlib.h>#include <unistd.h>//告诉驱动程序pid以及系统调用fcntl的头文件#include <sys/ioctl.h>#include <sys/types.h>//告诉驱动程序pid#include <sys/stat.h>#include <fcntl.h>//系统调用fcntl的头文件,文件控制定义#include <sys/select.h>#include <sys/time.h>#include <errno.h>//错误号定义#include <poll.h>#include <stdint.h>#include <asm/types.h>#include <sys/mman.h>#include <string.h>#include <malloc.h>#include <termios.h>    //PPSIX 终端控制定义#include <signal.h>//调用signal函数的头文件#include <pthread.h>//多线程程序设计需要#include <setjmp.h> //goto语句只能在函数内部跳转,而setjmp和longjmp函数可以在函数之间或不同文件之间跳转#include "uart.h"  //<>为系统头文件,""为自定义头文件#include "spiRf2401.h"#include "ArrayList.h"#include "ArrayQueue.h"#include "doubleLinkedList.h"#include "LinkedList.h"#include "LinkedStack.h"#include "LinkedQueue.h"/*********************************************关于延时函数*********************************************************  Linux中的延时函数:  (1)应用层:sleep(1);1S延时usleep(1);1US延时,1000US=1MS,1000MS=1S  (2)内核层:       #include <linux/delay.h>void ndelay(unsigned long nsecs); 纳秒级void udelay(unsigned long usecs); 微秒级void mdelay(unsigned long msecs); 毫秒级****************************************************************************************************************//***********************************************typedef和define**************************************************  typedef和define的区别:  (1)#define是预处理指令,在编译预处理时进行简单的替换,不作正确性检查,不管含义是否正确照样带入,只有在编译已被展开的源程序时才会发现可能的错误并报错;而typedef是在编译时处理的。它在自己的作用域内给一个已经存在的类型一个别名。    (2)typedef int * ptr与#define ptr int *的区别:作用都是用ptr代表int * ,但是二者不同,正如前面所说 ,#define在预处理时进行简单的替换,而typedef不是简单替换 ,而是采用如同定义变量的方法那样来声明一种类型。#define ptr int * ;ptr a, b; 相当于int * a, b只是简单的宏替换。typedef int* ptr;ptr a, b; a, b 都为指向int的指针,typedef为int* 引入了一个新的助记符,但是这个时候,如果使用stuct Node* a,b;时编译器会报错(意图是定义两个结构体指针变量),正确的定义方式为stuct Node* a,*b;。    (3)typedef int * pint与#define PINT int *   const pint p;//p不可更改,但p指向的内容可更改   const PINT p;//p可更改,但是p指向的内容不可更改。       pint是一种指针类型,const pint p 就是把指针给锁住了,p不可更改而const PINT p 是const int * p, 锁的是指针p所指的对象。    (4)#define不是语句,不要在行末加分号,否则会连分号一块置换。    (5)关于typedef和define的作用域       1) 不管是typedef还是define,都不能在定义之前使用;       2) typedef受函数范围影响,而define不受;       3) 不管是typedef还是define,其作用域都不会扩展到别的文件,即使是同一个程序的不同文件,也不能互相使用。    (6)typedef和结构体       注意:在C++中struct 的成员默认是公有的,而类的成员默认是私有的。struct 和 class 在其他方面是功能相当的。          struct        {          int num ;         }stu1; //只能在定义结构体时用一次,以后再也无法定义此结构体变量,缺乏灵活性。          struct student        {          int num ;         }stu1; //此处定义结构体时,顺便定义了结构体变量。          typedef struct student        {          int num ;         }stu1; //注意:此处并非结构体变量,而是结构体类型(相当于人的小名,相当于struct student)     typedef struct Node   {  int data;  pNode pNext;   }*pNode;            //编译出错   问题分析:C语言允许在结构中包含指向它自己的指针,可以在建立链表等数据结构的实现上看到无数这样的例子,上述代码的根本问题在于typedef的应用。新结构建立的过程中遇到了pNext域的声明,类型是pNode,要知道pNode表示的是类型的新名字,那么在类型本身还没有建立完成的时候,这个类型的新名字也还不存在,也就是说这个时候编译器根本不认识pNode。      解决方案:   typedef struct Node   {      int data;      struct Node *pNext;   }*pNode;****************************************************************************************************************/  /**********************************************关于Linux中内存管理*************************************************1、linux内核管理内存空间的分配,所有程序对内存空间的申请和其他操作,最终都会交给内核来管理。2、linux实现的是“虚拟内存系统”,对用户而言,所有内存都是虚拟的,也就是说程序并不是直接运行在物理内存上,而是运行在虚拟内存上,然后由虚拟内存转换到物理内存。3、linux将所有的内存都以页为单位进行划分,通常每一页是4KB;4、在对虚拟内存地址到物理内存地址进行转换时,内核会对地址的正确性进行检查,如果地址是合法的,内核就会提供对应的物理内存分页;如果是申请内存空间,内核就会检查空余的物理内存分页,并加以分配,如果物理内存空间不足,内核会拒绝此次申请;5、使用malloc分配的内存空间在虚拟地址空间上是连续的,但是转换到物理内存空间上有可能是不连续的,因为有可能相邻的两个字节是在不同的物理分页上;****************************************************************************************************************//*********************************************关于数据结构********************************************************1.打印的数据结构文档(包括大纲)。2.每个源码前的注释都大概说明了每种结构和操作3.知识结构:  (1)线性结构:顺序存储ArrayList.c , 离散存储LinkedList.c       线性存储的应用:用数组实现堆栈和队列,用链表实现堆栈和队列,双链表,递归  (2)非线性结构:树和图****************************************************************************************************************/void *thread1(void *str); void *thread2(void *str);void *thread3(void *str); void *thread4(void *str);void *thread5(void *str); void *thread6(void *str);  int ioSignal=0;int busErrSignal=0;int segvErrSignal=0;int illSignal=0; int intSignal=0;//中断信号标记jmp_buf buf;//长跳转参数void my_signal_fun(int signum){//根据C专家编程,系统并不支持在信号处理程序内部调用库函数(除非严格符合标准所限制的条件),这点必须注意。比如调用交互式I/O  printf函数。if ( signum == SIGIO ){ioSignal = 1;}else if ( signum == SIGBUS ){busErrSignal = 1;}else if ( signum == SIGSEGV ){segvErrSignal = 1;}else if ( signum == SIGILL ){illSignal = 1;}else{intSignal = 1;}}int main(void)//没有信号的时候执行主函数里面的,当捕获到信号后,执行信号函数里面的,相当于中断一下{//安装信号signal(SIGIO, my_signal_fun);//SIGIO表示io口有数据可以读写时将发送信号signal(SIGBUS, my_signal_fun);//SIGBUS表示发生总线错误时调用信号处理函数signal(SIGSEGV, my_signal_fun);//SIGSEGV表示发生段错误时调用信号处理函数,这里如果不安装,当本程序发生段违规后,操作系统会强行干掉本进程signal(SIGILL, my_signal_fun);//SIGILL表示发生非法指令异常时将发送信号,调用信号处理函数signal(SIGINT, my_signal_fun);//SIGINT表示发生中断时将发送信号,调用信号处理函数    比如按ctrl + cprintf("\n");switch ( setjmp(buf) ){case 0: printf("first time in main\n");break;case 1:printf("back in main\none SIGIO happen\nreturn 0\n");return 0;case 2:printf("back in main\none SIGBUS happen\nreturn 0\n");return 0;case 3:printf("back in main\none SIGSEGV happen\nreturn 0\n");return 0;case 4:printf("back in main\none SIGILL happen\nreturn 0\n");return 0;case 5:printf("back in main\none SIGINT happen\nreturn 0\n");return 0;}/*****************************创建三条线程,并处于就绪态************************/pthread_t pth1,pth2,pth3,pth4,pth5,pth6;int error1,error2,error3,error4,error5,error6;error1=pthread_create(&pth1,NULL,thread1,NULL); //创建线程,线程进入就绪模式if(error1!=0){printf("new thread1 is not create success! …\n");return -1;}error2=pthread_create(&pth2,NULL,thread2,NULL); //创建线程,线程进入就绪模式if(error2!=0){printf("new thread2 is not create success! …\n");return -1;}error3=pthread_create(&pth3,NULL,thread3,NULL); //创建线程,线程进入就绪模式if(error3!=0){printf("new thread3 is not create success! …\n");return -1;}error4=pthread_create(&pth4,NULL,thread4,NULL); //创建线程,线程进入就绪模式if(error4!=0){printf("new thread4 is not create success! …\n");return -1;}error5=pthread_create(&pth5,NULL,thread5,NULL); //创建线程,线程进入就绪模式if(error5!=0){printf("new thread5 is not create success! …\n");return -1;}error6=pthread_create(&pth6,NULL,thread6,NULL); //创建线程,线程进入就绪模式if(error6!=0){printf("new thread6 is not create success! …\n");return -1;}/*****************************创建n条线程,并处于就绪态************************//*如果不想阻塞主进程,可以调用pthread_detach函数*/pthread_join(pth1,NULL);//阻塞,让处于就绪态的线程开始执行,直到线程退出pthread_join(pth2,NULL);//阻塞,让处于就绪态的线程开始执行,直到线程退出pthread_join(pth3,NULL);//阻塞,让处于就绪态的线程开始执行,直到线程退出pthread_join(pth4,NULL);//阻塞,让处于就绪态的线程开始执行,直到线程退出pthread_join(pth5,NULL);//阻塞,让处于就绪态的线程开始执行,直到线程退出pthread_join(pth6,NULL);//阻塞,让处于就绪态的线程开始执行,直到线程退出printf("\n");printf("All program will end!\n");printf("\n");sleep(1);return 0;}//信号发生后报告void *thread1(void *str) {printf("here is thread1\n");int i=0;while(1){usleep(100000);if ( 1 == ioSignal  ){ioSignal = 0;printf("now got a SIGIO signal!\n");longjmp(buf,1);}else if ( 1 == busErrSignal ){busErrSignal = 0;printf("now got a bus error signal!\n");longjmp(buf,2);}else if ( 1 == segvErrSignal ){segvErrSignal = 0;printf("now got a segmentation violation error signal!\n");longjmp(buf,3);}else if ( 1 == illSignal ){illSignal = 0;printf("now got a illegal instruction signal!\n");longjmp(buf,4);}else if ( 1 == intSignal ){intSignal = 0;printf("\n");printf("now got a SIGINT signal!\n");longjmp(buf,5);}else{//printf("no signal!\n");sleep(1);//break;}}return NULL;}//线性结构中数组的存储和操作void *thread2(void *str) {printf("here is thread2\n");/*int i=0,val=0;struct arrayList arr;struct arrayList *pArray;pArray = &arr;init_arraylist(pArray,10);//showArrayList(&arr);    addToEnd(pArray,234);    addToEnd(pArray,23);addToEnd(pArray,653);    addToEnd(pArray,99);addToEnd(pArray,235);    addToEnd(pArray,57);showArrayList(pArray);printf("pArray->len=%d,pArray->cnt=%d\n",pArray->len,pArray->cnt);deleteElement(pArray,3,&val);showArrayList(pArray);printf("pArray->len=%d,pArray->cnt=%d,val=%d\n",pArray->len,pArray->cnt,val);insertArrayList(pArray,3,999);showArrayList(pArray);printf("pArray->len=%d,pArray->cnt=%d\n",pArray->len,pArray->cnt);inversionArrayList(pArray);showArrayList(pArray);           sortArrayList(pArray);showArrayList(pArray);    freeArrayList(pArray);  showArrayList(pArray);//前面已经释放了pBase指针,即释放了动态分配的内存,并把pBase设为NULL,这里再使用pBase指针就会发生段错误,从而程序捕获段违规信号*/struct structEntry{    int intEntry;    char charEntry[20];    struct list_head list;};struct structEntry entry;return NULL;}void *thread3(void *str) {printf("here is thread3\n");/*int pVal=0;struct Node*  pHead ; pHead = creatLinkedList();traverseLinkedList(pHead);printf("the list length=%d\n",lengthLinkedList(pHead));printf("sortLinkedList\n");sortLinkedList(pHead);traverseLinkedList(pHead);printf("insertLinkedList\n");insertLinkedList(pHead,7,222);traverseLinkedList(pHead);printf("deleteLinkedList\n");deleteLinkedList(pHead,1,&pVal);traverseLinkedList(pHead);printf("the list length=%d,pVal=%d\n",lengthLinkedList(pHead),pVal);freeLinkedList(pHead);traverseLinkedList(pHead);*/return NULL;}void *thread4(void *str) {printf("here is thread4\n");/*int depth=0;int val=0;struct LinkedStack S;initStack(&S);linkedStackPush(&S,1);linkedStackPush(&S,2);linkedStackPush(&S,3);linkedStackPush(&S,4);linkedStackPush(&S,5);traverseLinkedStack(&S,&depth);printf("the LinkedListStack depth is %d\n",depth);linkedStackPop(&S,&val);traverseLinkedStack(&S,&depth);printf("the LinkedListStack depth is %d\n,POP data is %d\n",depth,val);clearLinkedStack(&S);traverseLinkedStack(&S,&depth);printf("the LinkedListStack depth is %d\n",depth);*/return NULL;}//for nRF24l01,SPI0,ARM-LINUXvoid *thread5(void *str){printf("here is thread5\n");/*int isSendSuccess=0;unsigned char txBuf[2]={0x08,0x41};unsigned char rxBuf[2]={0,0};unsigned char rfTxAddr[5]={0x70,0x70,0x84,0x06,0x17};unsigned char rfRxAddr[5]={0x70,0x70,0x84,0x06,0x17};unsigned char startTransfer[2]={0,0};int spi0fd=0,gpiofd=0;spi0fd = spiOpen();if( -1 == spi0fd ){printf("can't open spi device 0\n");exit(-1);}else {printf("spi open successful\n");}gpiofd = gpioOpen();if( -1 == gpiofd ){printf("can't open gpio 0\n");exit(-1);}else {printf("gpio 0 open successful\n");}if ( -1 == spiSet(spi0fd) ){printf("can't set spi device 0\n");exit(-1);}else{printf("spi 0 set successful\n");}nRF24L01Init(gpiofd);rfBeginTransfer(spi0fd,0xff,startTransfer);//启动传输printf("startTransfer[0]=%#x,startTransfer[1]=%#x\n",startTransfer[0],startTransfer[1]);if ( -1 == nRF2401SelfCheckExist(spi0fd) ){printf("\nnRF2401SelfCheckExist():HOST'S NRF24L01 is not Exist\n");}else{printf("\nnRF2401SelfCheckExist(): HOST'S NRF24L01 is  Exist\n");}while(1){TX_Mode(gpiofd,spi0fd,rfTxAddr,txBuf);        isSendSuccess=RF_Send_to_MSub(spi0fd);   if( 1 == isSendSuccess) {RX_Mode(gpiofd,spi0fd,rfRxAddr);RF_Revc_from_MSub(spi0fd,rxBuf); }        usleep(200000);}spiClose(spi0fd);gpioClose(gpiofd);*/return NULL;}void *thread6(void *str) {printf("here is thread6\n");/*int val = 0;struct arrayQueue Q;struct arrayQueue * pQ = &Q;arrayQueueCreat(&Q,6);printf("entry the array queue!\n");enArrayQueue(pQ,1);enArrayQueue(pQ,2);enArrayQueue(pQ,3);enArrayQueue(pQ,4);enArrayQueue(pQ,5);//enArrayQueue(pQ,3);traverseArrayQueue(pQ);printf("pQ->arrayLen = %d,pQ->queueLen = %d\n",pQ->arrayLen,pQ->queueLen);printf("out the array queue!\n");outArrayQueue(pQ,&val);outArrayQueue(pQ,&val);outArrayQueue(pQ,&val);outArrayQueue(pQ,&val);outArrayQueue(pQ,&val);//outArrayQueue(pQ,&val);traverseArrayQueue(pQ);printf("pQ->arrayLen = %d,pQ->queueLen = %d,val = %d\n",pQ->arrayLen,pQ->queueLen,val);*//*int len=0;int val=0;struct linkedQueue Queue;struct linkedQueue *pQueue = &Queue;linkedQueueCreat(pQueue);enLinkedQueue(pQueue,1);enLinkedQueue(pQueue,2);enLinkedQueue(pQueue,3);enLinkedQueue(pQueue,4);enLinkedQueue(pQueue,5);traverseLinkedQueue(pQueue,&len);printf("len = %d\n",len);outLinkedQueue(pQueue,&val);printf("outLinkedQueue data is  = %d\n",val);traverseLinkedQueue(pQueue,&len);printf("len = %d\n",len);outLinkedQueue(pQueue,&val);printf("outLinkedQueue data is  = %d\n",val);traverseLinkedQueue(pQueue,&len);printf("len = %d\n",len);enLinkedQueue(pQueue,5);traverseLinkedQueue(pQueue,&len);printf("len = %d\n",len);*/return NULL;}关于数据结构相关可以查看文件:ArrayList.cLinkedList.cArrayQueue.cLinkedQueue.cLinkedStack.c 

0 0
原创粉丝点击