PDA

View Full Version : thread syncronization



havij000
11th November 2013, 12:20
Hi every body,

I am new to qt, and now I am writing a network application program with 3 threads additional to the main gui thread.
one thread sniff the lan and recieve ethernet packets, one of the other thread process the data and inorder the recieved data and the last one is sending data to another computer through LAN by TCP sockets.

The problem that I have is that, I dont know how I should inform the other thread that the data is completed and it should send it through the LAN????
:crying::confused:

Thanks

toufic.dbouk
11th November 2013, 19:12
When the thread is done processing data and ready to send emit a signal, catch it in the other thread or your main thread and then throw it again for the specific thread, depending on your implementation and design. So basically its a matter of Signals and Slots.

Good Luck.

anda_skoa
11th November 2013, 19:23
Are you sure you want that many threads?

E.g. why have a thread for sending?

Anyway, there are a number of ways to move data between threads, the most convenient one is Qt signal/slots.

Cheers,
_

havij000
12th November 2013, 12:12
yes I need this number of thread, I need a thread to send data through LAN to a remote computer by tcp protocol.
I dont want to send data between threads, I just want to inform the send thread about the completion of process task. and after informing the send thread force it to send the data.

Added after 15 minutes:

I have already use signal and slot but unfortunately it does not work. The precess thread emit but the solt in the send thread does not work.

toufic.dbouk
12th November 2013, 17:49
Yes Signals and Slots is a way to inform about status of threads example when a thread is done its task inform other threads that it is done.

I have already use signal and slot but unfortunately it does not work. The precess thread emit but the solt in the send thread does not work.
Well you have something wrong with your code , so please post a minimal code reproducing the problem in order to help you.

Good Luck.

anda_skoa
13th November 2013, 11:26
yes I need this number of thread, I need a thread to send data through LAN to a remote computer by tcp protocol.


Any why do you need a separate thread for that?
Any specific reason why the main thread can't do that?



I dont want to send data between threads, I just want to inform the send thread about the completion of process task. and after informing the send thread force it to send the data.

You don't have to send the data through the signal, a signal without arguments will do as well if it only triggers data fetching in the receiver thread.



I have already use signal and slot but unfortunately it does not work. The precess thread emit but the solt in the send thread does not work.


Is the receiver thread's event loop running?

Cheers,
_

havij000
16th November 2013, 09:11
yes, both the loop of receive thread and the process thread are running and I use emit in the process thread.


You don't have to send the data through the signal, a signal without arguments will do as well if it only triggers data fetching in the receiver thread.



I dont send data through signal I just send the index of a common data through signal.



Any why do you need a separate thread for that?
Any specific reason why the main thread can't do that?


Since I will have an scope in the GUI to show a copy of data, I need a seprate thread to send the data.

Added after 4 minutes:

this is the emit of the signal


emit Q_Sample_Completed(data_prcss_child_1, indx);


this is the connect part.



connect(prcs_thrd_child, SIGNAL(Q_Sample_Complete(Data_Class*,int)), this, SLOT(onQ_Sample_Completed(Data_Class*,int)));


this is on of the slot codes



void Client_Thread::onQ_Sample_Completed(Data_Class *mdata, int index_num)
{
data_class_child_2 = mdata;

int i = index_num;

/*
//----------network section--------------------
int sock;
struct sockaddr_in server, localAddr;
//char message[1000] ;
char server_reply[2000];





this->msleep(1);

//Create socket
sock = socket(AF_INET , SOCK_STREAM , 0);
if (sock == -1)
{
printf("Could not create socket");
}
puts("Socket created");

server.sin_addr.s_addr = inet_addr("192.168.100.150");
server.sin_family = AF_INET;
server.sin_port = htons( 8888 );


//local address
localAddr.sin_family = AF_INET;
localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
localAddr.sin_port = htons(8888);

int rc;
rc = bind(sock, (struct sockaddr *) &localAddr, sizeof(localAddr));

if(rc < 0)
{
printf("cannot bind port TCP\n");
perror("error ");
exit(1);
}

//Connect to remote server
if (::connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
{
perror("connect failed. Error");
return ;
}
puts("Connected\n");

//keep communicating with server

//--------------end of network section------------------------
*/

char message_1[8442];


//--------------send section--------------------------
memcpy(message_1, &data_class_child_2->Q_smpl_pckt_ddc_1[i].total_hdr, 6);
memcpy(&message_1[6], &data_class_child_2->Q_smpl_pckt_ddc_1[i].A2Dhdr, 36);
memcpy(&message_1[42], &data_class_child_2->Q_smpl_pckt_ddc_1[i].CmpltData_prt_1, 1400);
memcpy(&message_1[1442], &data_class_child_2->Q_smpl_pckt_ddc_1[i].CmpltData_prt_2, 1400);
memcpy(&message_1[2842], &data_class_child_2->Q_smpl_pckt_ddc_1[i].CmpltData_prt_3, 1400);
memcpy(&message_1[4242], &data_class_child_2->Q_smpl_pckt_ddc_1[i].CmpltData_prt_4, 1400);
memcpy(&message_1[5642], &data_class_child_2->Q_smpl_pckt_ddc_1[i].CmpltData_prt_5, 1400);
memcpy(&message_1[7042], &data_class_child_2->Q_smpl_pckt_ddc_1[i].CmpltData_prt_6, 1400);

if( send(sock , message_1 , strlen(message_1) , 0) < 0)
{
puts("Send failed\n");
return ;
}

printf("SEND a complete Q Pkt\n");

//&&&&&&&&&&&&&&&&&&&&&&&&&&& set the flag as the buffer is free &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

data_class_child_2->Q_smpl_pckt_ddc_1[i].valid = false;
data_class_child_2->Q_smpl_pckt_ddc_1[i].total_set = false;

data_class_child_2->Q_smpl_pckt_ddc_1[i].flag_scop = false;
data_class_child_2->Q_smpl_pckt_ddc_1[i].flag_snd = false;

data_class_child_2->Q_smpl_pckt_ddc_1[i].part1_set = false;
data_class_child_2->Q_smpl_pckt_ddc_1[i].part2_set = false;
data_class_child_2->Q_smpl_pckt_ddc_1[i].part3_set = false;
data_class_child_2->Q_smpl_pckt_ddc_1[i].part4_set = false;
data_class_child_2->Q_smpl_pckt_ddc_1[i].part5_set = false;
data_class_child_2->Q_smpl_pckt_ddc_1[i].part6_set = false;
data_class_child_2->Q_smpl_pckt_ddc_1[i].part7_set = false;


data_class_child_2->Q_smpl_pckt_ddc_1[i].arvd_pkts = 0;

printf("FREE Q sample buffer number: %d \n", i);

//&&&&&&&&&&&&&&&&&&&&&&&&&&& end of set part &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

//--------------------------------------------------end of the send section---------------------------------------





}

anda_skoa
16th November 2013, 10:29
That connect is that in the QThread subclass? Do you want the slot be executed in the thread context or the main thread context?

Also: the data access code seems to miss any proper thread synchronisation.
One other thing that looks weird is usage of blocking socket API instead of using event driven QTcpSocket.

Can you create a simple example where the reader thread just uses a QTimer to create random data?

Cheers,
_

havij000
18th November 2013, 07:05
the data access code seems to miss any proper thread synchronisation.

Its not the complete code.

havij000
23rd November 2013, 12:15
In any cae how can I tell another thread to run just for a while?

:confused:

anda_skoa
23rd November 2013, 12:39
QThread instances do that by default, i.e. they run their own event loop.

If you derive from QThread and reimplement run(), then you can call exec() to start the event loop manually.

Cheers,
_

toufic.dbouk
23rd November 2013, 14:17
In any case when you run the thread it will run in its own event loop and hence it will run just for a while till the process its executing finishes.

havij000
26th November 2013, 12:43
you mean that in each iteration I should use exec() to start the other thread once?

toufic.dbouk
26th November 2013, 17:43
Not really , exec() will start the thread that will run in its own event loop.
Do you mean you want to start the thread in a loop where you iterate several times ? and on each iteration the exec() function will be executed ?