1. 程式人生 > >樹莓派3B Linux下C++多執行緒程式設計

樹莓派3B Linux下C++多執行緒程式設計

下面的程式碼手動建立了兩個執行緒,一個執行緒是讀取串列埠的資料,另一個執行緒是通過UDP來讀取網路通訊收到的資料。加上main函式的執行緒,一共三個執行緒。

先簡單講一下多執行緒的建立,

    pthread_t serial;
    int ser = pthread_create(&serial,NULL,connectSerial,NULL);
    if(ser != 0)
    {
        std::cout << "pthread creat serial error"<<std::endl;
    }

connectSerial是建立的執行緒的入口函式。

void *connectSerial(void *args)
{
    int fd;
    if(wiringPiSetup() < 0)
        exit(1);  

    if((fd = serialOpen("/dev/ttyAMA0",115200)) < 0)
        exit(1);  

    //long int i = 0;
    int datareceive = 0;
    while(1)
    {
        datareceive = serialGetchar(fd);
        intToHex(datareceive,&basebuff[baselen],2
); baselen += 2; } serialClose(fd); }

完整程式碼:

#include <stdio.h>
#include <iostream>
#include <wiringPi.h>
#include <wiringSerial.h>
#include <vector>
#include <unistd.h>
#include <sys/types.h>  
#include <sys/socket.h>  
#include <pthread.h>  
#include <netinet/in.h> #include <string.h> #include <stdlib.h> #include <arpa/inet.h> std::vector<char> basebuff(1024*1024*10,0); std::vector<char> roverbuff(1024*1024*10,0); long int baselen = 0; long int roverlen = 0; void *creatWiFi(void *args) { struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(8000); addr.sin_addr.s_addr = htonl(INADDR_ANY); int sock; if ( (sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); exit(1); } if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("bind"); exit(1); } //long int roverptr = 0; struct sockaddr_in clientAddr; int n; int len = sizeof(clientAddr); while (1) { n = recvfrom(sock,&roverbuff[roverlen], 511, 0, (struct sockaddr*)&clientAddr, (socklen_t*)&len); if (n>0) { roverlen += n; } else { perror("recv"); break; } } } void intToHex(int dec,char *output,int length) { const char * hex = "0123456789ABCDEF"; for(int i = 0;i < length;i++) { output[length-i-1] = hex[(dec >> i * 4) & 0x0F]; } } void *connectSerial(void *args) { int fd; if(wiringPiSetup() < 0) exit(1); if((fd = serialOpen("/dev/ttyAMA0",115200)) < 0) exit(1); //long int i = 0; int datareceive = 0; while(1) { datareceive = serialGetchar(fd); intToHex(datareceive,&basebuff[baselen],2); baselen += 2; } serialClose(fd); } int main() { pthread_t serial; int ser = pthread_create(&serial,NULL,connectSerial,NULL); if(ser != 0) { std::cout << "pthread creat serial error"<<std::endl; } pthread_t wifi; int wif = pthread_create(&wifi,NULL,creatWiFi,NULL); if(wif != 0) { std::cout << "pthread creat serial error"<<std::endl; } FILE *base; base = fopen("/home/pi/wifi/base.txt","w+"); if(base == NULL) { std::cout << "basefileerror"; return 1; } FILE *rover; rover = fopen("/home/pi/wifi/rover.txt","w+"); if(rover == NULL) { std::cout << "roverfileerror"; return 1; } long int blen = 0; long int rlen = 0; while(1) { if(baselen - blen >= 100) { std::cout<<"savebasebuff!"<<std::endl; fwrite(&basebuff[blen],sizeof(char),100,base); } if(roverlen - rlen >= 100) { std::cout<<"saveroverbuff!"<<std::endl; fwrite(&roverbuff[rlen],sizeof(char),100,rover); } } pthread_exit(NULL); return 0; }

上面的程式碼用到了Wiring Pi庫,所以編譯語句:

g++ -Wall serial.cpp -o serial -lwiringPi -lpthread

如果沒有使用wiringPi庫的編譯時去掉-lwiringPi。