Multi-thread GUI execution
-
Hello, I am working on a multi-process program which has three different threads. One of them has to execute a GUI created via Qt. I want to execute the GUI in one separate thread and this is the code:
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <sys/types.h> #include <unistd.h> #include <time.h> #include <sys/types.h> #include <fcntl.h> #include <sys/stat.h> #include <errno.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #include "ADS1256_DAC8532_lib.h" #include "addstrings2.h" #include "changetypes.h" #include "ReadWriteSock.h" #include "Socket.h" int ppres1[2]; int ppres2[2]; int ppos[2]; int pservo[2]; void *UDPProtocol(){ struct sockaddr_in Directionwrite; int Descriptor,aux; struct sockaddr_in Recv; int RecvAddrSize=sizeof(Recv); char SendDataADC[28]; char press1[8]; char press2[8]; char pos[8]; char cservo[6]; struct timespec start,stop; // Enlever apres les tests int l=0; double secs=0; Directionwrite.sin_family = AF_INET; Directionwrite.sin_addr.s_addr=inet_addr("169.254.51.37"); Directionwrite.sin_port = htons(59216); do{ Descriptor = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); printf("\n El socket vale %d", Descriptor); } while(Descriptor==-1); do{ printf("\n Llego2"); aux=connect(Descriptor, (struct sockaddr *)&Directionwrite, sizeof (Directionwrite)); } while(aux==-1); while(1){ clock_gettime(CLOCK_REALTIME, &start); read(ppres1[0],press1,8); read(ppres2[0],press2,8); read(ppos[0],pos,8); addstringsADCv2(SendDataADC,press1,press2,pos); writeSocket(Descriptor,SendDataADC,strlen(SendDataADC)); int b=recvfrom(Descriptor, cservo,5,0,(struct sockaddr *) &Recv, &RecvAddrSize); cservo[4]='\0'; write(pservo[1],cservo,4); //printf("\n %d", b); clock_gettime(CLOCK_REALTIME,&stop); secs=secs+(((double)stop.tv_sec*1000+(double)(stop.tv_nsec/1000000)-((double)start.tv_sec*1000+(double)start.tv_nsec/1000000))); l++; } //(secs=(((double)stop.tv_sec+(double)(stop.tv_nsec/1000000000)-((double)start.tv_sec+(double)start.tv_nsec/1000000000))/250); printf("\n %.16g milliseconds", secs/250); printf("\n Fin"); } void *ADCProgram(){ int cuenta=0; float servo=0; struct timespec start,stop; float pressure1=0; float position=0; float pressure2=0; char press1[8]; char press2[8]; char pos[8]; char cservo[6]="0.00"; int32_t adc[8]; int ch_num_tru=3; while(1){ while((ADS1256_Scan()==0)); for(cuenta=0;cuenta<3;cuenta++){ adc[cuenta] = ADS1256_GetAdc(cuenta); adc[cuenta] = (adc[cuenta] * 100) / 167; switch(cuenta){ case 0: position=adc[cuenta]; position=position/1000000; position=2*position; position=(position-2,5); position=position/100; passtocharpos(position,pos); write(ppos[1],pos,8); break; case 1: pressure1=adc[cuenta]; pressure1=pressure1/1000000; pressure1=(pressure1-0.533)/0.4; pressure1=pressure1*100000; if(pressure1<0) pressure1=0; passtocharpress(pressure1,press1); fflush(stdin); write(ppres1[1],press1,8); break; case 2: pressure2=adc[cuenta]; pressure2=pressure2/1000000; pressure2=(pressure2-0.533)/0.4; pressure2=pressure2*100000; if(pressure2<0) pressure2=0; passtocharpress(pressure2,press2); write(ppres2[1],press2,8); break; default: } } cuenta=0; read(pservo[0],cservo,5); cservo[5]='\0'; servo=atof(cservo); servo=(servo/4)+2.5; Write_DAC8552(0x30, Voltage_Convert(5.0,servo)); } bcm2835_spi_end(); bcm2835_close(); } void *GUIexec(){ execl("./GUIQTv2", (char *) NULL); } int main(){ int rc1,rc2,rc3; pthread_t thread1, thread2, thread3; pipe(ppres1); pipe(ppres2); pipe(ppos); pipe(pservo); bcm2835_init(); bcm2835_spi_begin(); bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_LSBFIRST ); // The default bcm2835_spi_setDataMode(BCM2835_SPI_MODE1); // The default bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_8192); // The default bcm2835_gpio_fsel(SPICS, BCM2835_GPIO_FSEL_OUTP);// bcm2835_gpio_write(SPICS, HIGH);//Why do we need it?? bcm2835_gpio_fsel(DRDY, BCM2835_GPIO_FSEL_INPT); bcm2835_gpio_set_pud(DRDY, BCM2835_GPIO_PUD_UP); ADS1256_CfgADC(ADS1256_GAIN_1, ADS1256_15SPS); ADS1256_StartScan(0); if((rc1=pthread_create(&thread1, NULL, &UDPProtocol, NULL))){ printf("Thread creation failed %d\n", rc1); } if((rc2=pthread_create(&thread2, NULL, &ADCProgram, NULL))){ printf("Thread creation failed %d\n", rc2); } if((rc3=pthread_create(&thread3, NULL, &GUIexec, NULL))){ printf("Thread creation failed %d\n", rc3); } //Wait for all the threads pthread_join(thread1,NULL); pthread_join(thread2, NULL); pthread_join(thread3, NULL); return 0; }
The problem comes in the execl command in the thread GUIexec(). When using the execl function that starts the GUI executable created via QTCreator, the other threads stop workinf. I have all the codes of the GUI. Does anyone know how I can execute the interface in one thread without stopping the others? Thanks beforehand.
-
execl just overlays the current process with new executable. You should do fork and then exec. That should create the new process.
-
@dheerendra so then in the thread I created, you propose to create a fork()? So in the GUIexec() function I should do a fork() and then an exec()?
-
Thread will not create the new process. You need to create the new process using the fork and overlay the new executable using excel
-
@dheerendra Therefore, should I fork in the main program and then execl and thread, or inside my thread fork and then execl?
-
Do fork and exec in your thread. Just find example on how to do fork/exec. Then implement the same in thread.