Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Multi-thread GUI execution
QtWS25 Last Chance

Multi-thread GUI execution

Scheduled Pinned Locked Moved Unsolved General and Desktop
guithreadmultithreadsexecutable
7 Posts 3 Posters 2.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    sebs
    wrote on last edited by
    #1

    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.

    1 Reply Last reply
    0
    • dheerendraD Offline
      dheerendraD Offline
      dheerendra
      Qt Champions 2022
      wrote on last edited by
      #2

      execl just overlays the current process with new executable. You should do fork and then exec. That should create the new process.

      Dheerendra
      @Community Service
      Certified Qt Specialist
      http://www.pthinks.com

      S 1 Reply Last reply
      1
      • dheerendraD dheerendra

        execl just overlays the current process with new executable. You should do fork and then exec. That should create the new process.

        S Offline
        S Offline
        sebs
        wrote on last edited by
        #3

        @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()?

        1 Reply Last reply
        0
        • dheerendraD Offline
          dheerendraD Offline
          dheerendra
          Qt Champions 2022
          wrote on last edited by
          #4

          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
          @Community Service
          Certified Qt Specialist
          http://www.pthinks.com

          S 1 Reply Last reply
          0
          • dheerendraD dheerendra

            Thread will not create the new process. You need to create the new process using the fork and overlay the new executable using excel

            S Offline
            S Offline
            sebs
            wrote on last edited by
            #5

            @dheerendra Therefore, should I fork in the main program and then execl and thread, or inside my thread fork and then execl?

            jsulmJ 1 Reply Last reply
            0
            • dheerendraD Offline
              dheerendraD Offline
              dheerendra
              Qt Champions 2022
              wrote on last edited by
              #6

              Do fork and exec in your thread. Just find example on how to do fork/exec. Then implement the same in thread.

              Dheerendra
              @Community Service
              Certified Qt Specialist
              http://www.pthinks.com

              1 Reply Last reply
              0
              • S sebs

                @dheerendra Therefore, should I fork in the main program and then execl and thread, or inside my thread fork and then execl?

                jsulmJ Offline
                jsulmJ Offline
                jsulm
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @sebs What I don't understand: you want an application with 3 threads, right? But why do you create new process?

                https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                2

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved