Thread handling in TCP server in C - network-programming

This is my first post here, so I'd like to say hello to everyone.
I am facing some problems with writing a TCP, I want to have a separate thread that allows user to type quit instruction to terminate process. The problem is that it doesn't seem to be running. The programme pauses on accept and I am unable to pass anything to the thread function.
The thread function:
void *loop_stop()
{
while(progr_control != 'q')
progr_control = getchar();
return NULL;
}
And the main (I ommited some code I think is not causing problems):
pthread_t thread_id;
pthread_create(&thread_id, NULL, loop_stop, NULL);
do
{
listen(sock_fd, 5);
int addr_len = sizeof(client_addr);
if( (new_sock_fd = accept(sock_fd, (struct sockaddr *) &client_addr, &addr_len)) < 0)
{
perror("Problems with incoming connection");
return -1;
}
else
//here is the ommited part-as I've said this loop stops at accept
}while(progr_control != 'q');
If anyone could please find the bug, or suggest other way of handling with the task, I'd be grateful

As Brian mentioned:
'accept' will make the thread wait for incomming connection, so no "quit check" is possible. The alternative is to use ctrl+c to quit instead.

Related

Whats the difference between pthread_join and pthread_mutex_lock?

The following code is taken from this site and it shows how to use mutexes. It implements both pthread_join and pthread_mutex_lock:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *functionC();
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int counter = 0;
main()
{
int rc1, rc2;
pthread_t thread1, thread2;
/* Create independent threads each of which will execute functionC */
if( (rc1=pthread_create( &thread1, NULL, &functionC, NULL)) )
{
printf("Thread creation failed: %d\n", rc1);
}
if( (rc2=pthread_create( &thread2, NULL, &functionC, NULL)) )
{
printf("Thread creation failed: %d\n", rc2);
}
/* Wait till threads are complete before main continues. Unless we */
/* wait we run the risk of executing an exit which will terminate */
/* the process and all threads before the threads have completed. */
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
exit(EXIT_SUCCESS);
}
void *functionC()
{
pthread_mutex_lock( &mutex1 );
counter++;
printf("Counter value: %d\n",counter);
pthread_mutex_unlock( &mutex1 );
}
I ran the code as given above as it is and it produced following result:
Counter value: 1
Counter value: 2
But in the second run i removed "pthread_mutex_lock( &mutex1 );" and "pthread_mutex_unlock( &mutex1 );" . I compiled and ran the code, it again produced the same result.
Now the thing that confuses me is why mutex lock is used in above code when same thing can be done without it (using pthread_join)? If pthread_join prevents another thread from running untill the first one has finished then i think it would already prevent the other thread from accessing the counter value. Whats the purpose of pthread_mutex_lock?
The join prevents the starting thread from running (and thus terminating the process) until thread1 and thread2 finish. It doesn't provide any synchronization between thread1 and thread2. The mutex prevents thread1 from reading the counter while thread2 is modifying it, or vice versa.
Without the mutex, the most obvious thing that could go wrong is that thread1 and thread2 run in perfect synch. They each read zero from the counter, each add one to it, and each output "Counter value: 1".

pthread_kill ends calling program

I am working on Ubuntu 12.04.2 LTS. I have a strange problem with pthread_kill(). The following program ends after writing only "Create thread 0!" to standard output. The program ends with exit status 138.
If I uncomment "usleep(1000);" everything executes properly. Why would this happen?
#include <nslib.h>
void *testthread(void *arg);
int main() {
pthread_t tid[10];
int i;
for(i = 0; i < 10; ++i) {
printf("Create thread %d!\n", i);
Pthread_create(&tid[i], testthread, NULL);
//usleep(1000);
Pthread_kill(tid[i], SIGUSR1);
printf("Joining thread %d!\n", i);
Pthread_join(tid[i]);
printf("Joined %d!", i);
}
return 0;
}
void sighandlertest(int sig) {
printf("print\n");
pthread_exit();
//return NULL;
}
void* testthread(void *arg) {
struct sigaction saction;
memset(&saction, 0, sizeof(struct sigaction));
saction.sa_handler = &sighandlertest;
if(sigaction(SIGUSR1, &saction, NULL) != 0 ) {
fprintf(stderr, "Sigaction failed!\n");
}
printf("Starting while...\n");
while(true) {
}
return 0;
}
If the main thread does not sleep a bit before raising the SIGUSR1, the signal handler for the thread created most propably had not been set up, so the default action for receiving the signal applies, which is ending the process.
Using sleep()s to synchronise threads is not recommended as not guaranteed to be reliable. Use other mechanics here. A condition/mutex pair would be suitable.
Declare a global state variable int signalhandlersetup = 0, protect access to it by a mutex, create the thread, make the main thread wait using pthread_cond_wait(), let the created thread set up the signal handle for SIGUSR1, set signalhandlersetup = 0 and then signal the condition the main thread is waiting on using pthread_signal_cond(). Finally let the main thread call pthread_kill() as by your posting.

a call to GetMessage causes a thread to stop

I am writing a multi-threaded application using Borland C++ (Delphi Forms). I have recently learned that I can use Windows' Messaging Service within these classes when I call the PostThreadMessage() function:
System = new STSystem(SystemName,1000,1,NULL);
while (PostThreadMessage(System->ThreadID,ST_MSG_SYSTEM_INIT,0,0) == 0)
{
Sleep(0);
};
The above seems to work just fine. The issue lies on the retrieval end of this process inside of the Thread Execution function:
void __fastcall STSystem::Execute()
{
ST_Message STMSG;
while(FStatus != Destroyed)
{
FHeartBeat++;
if(GetMessage(MSG,NULL,ST_MSG_SYSTEM_START,ST_MSG_SYSTEM_END))
{
STMSG.Value = MSG->wParam;
if((STMSG.dSYS + (8*STMSG.dSEC) + (64*STMSG.dDEP)) == FSystemID)
{
RXMessages[RxQueueIn++] = STMSG.MSG; // Message
RXMessages[RxQueueIn++] = MSG->lParam; // Data
}
}
if(TaskList->Count>0)
ProcessTask();
if(RxQueueIn!=RxQueueOut)
ProcessRxMessage();
if(TxQueueIn!=TxQueueOut)
ProcessTxMessage();
Sleep(0);
};
}
The above works for about two thread cycles and then stops; the thread stops, not the program. I have tried using the PeekMessage() function instead of the GetMessage() function in the IF clause following the FHeartbeat++ counter. This prevents the thread from stopping however, the INIT message sent in the first block of code is still not found.
I hope this example is not too specific. I have tried to leave in anything that was pertinent. Basically, this is a message pump for a class that has no window.
GetMessage() blocks the calling thread when there are no messages to retrieve. Like Luis said, you need to make sure the thread has a message queue before you start posting messages to it, and you need to check the return value of PostThreadMessage() for failures. A message queue is not created in a thread until any user32.dll function is called within the thread for the first time. For example:
System = new STSystem(SystemName,1000,1,NULL);
while (!System->Ready)
Sleep(100);
if (!PostThreadMessage(System->ThreadID,ST_MSG_SYSTEM_INIT,0,0))
{
DWORD err = GetLastError();
//...
}
void __fastcall STSystem::Execute()
{
// create a message queue
PeekMessage(MSG, NULL, 0, 0, PM_NOREMOVE);
Ready = true;
ST_Message STMSG;
while(FStatus != Destroyed)
{
FHeartBeat++;
if(GetMessage(MSG,NULL,ST_MSG_SYSTEM_START,ST_MSG_SYSTEM_END)) // or PeekMessage()
{
STMSG.Value = MSG->wParam;
if((STMSG.dSYS + (8*STMSG.dSEC) + (64*STMSG.dDEP)) == FSystemID)
{
RXMessages[RxQueueIn++] = STMSG.MSG; // Message
RXMessages[RxQueueIn++] = MSG->lParam; // Data
}
}
if(TaskList->Count>0)
ProcessTask();
if(RxQueueIn!=RxQueueOut)
ProcessRxMessage();
if(TxQueueIn!=TxQueueOut)
ProcessTxMessage();
Sleep(0);
};
}
To send messages to a tread it must have a message queue, in the remarks section of this link:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644946(v=vs.85).aspx
you can fine the steps reqired to create a message queue for a thread.
By the way, if PostThreadMessage returns 0 (FALSE), there is an error and you must check the value returned by GetLastError.

pthread_Join can't return after call pthread_cancel?

I used Eclispse Indigo + CDT 8.0.2 + cygwin to develope a multi-thread systerm, the code is below:
pthread_mutex_t mutexCmd = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t signalCmd = PTHREAD_COND_INITIALIZER;
void * Func(void * arg)
{
int iStatus;
while (1)
{
int a = 1;
pthread_cleanup_push(pthread_mutex_unlock, &mutexCmd);
pthread_mutex_lock(&mutexCmd);
iStatus = pthread_cond_wait(&signalCmd, &mutexCmd);
if (iStatus) {
err_abort(iStatus, "signalCmd status error");
}
if(arg->Cmd != navi_Go) //Just a command tag;
{
pthread_mutex_unlock(&(pNaviCtrl->mutexCmd));
continue;
}
//do some work
//.....
pthread_mutex_unlock(&mutexCmd);
pthread_cleanup_pop(1);
}
//pthread_detach(pthread_self());
return NULL;
}
int main()
{
int iStatus = 0;
pthread = tid;
iStatus = pthread_create(&tid;NULL, Func, NULL);
if(iStatus)
{
err_abort(iStatus, "Start pthread error");
}
// do some work
...
//Cancel thread
void * retval;
iStatus = pthread_cancel(tid)
iStatus = pthread_join(tid; &retval);
if(iStatus){
err_abort(iStatus,"Stop thread error");
}
return iStatus;
}
where program run, it stop at "iStatus = pthread_join(tid1; &retval);" couldn't go forward anymore, I think the thread could be happed to deadlock, but can't find the reason. I supposed after call pthread_cancel(), the thread will exit and return to the pthread_join(),
who can tell me what's wrong with my code?
Don't put cleanup_push and _pop inside the while loop. Don't call them more than once. If you look at them, they are macros that wrap the code between them in { }. They setup a longjump that is used when you call pthread_cancel.
pthread_cleanup_pop(1) tells the pthread library to not only pop the cleanup entry off the stack, but to also execute it. So that call will also implicitly call:
pthread_mutex_unlock(&mutexCmd);
Since you've already unlocked the mutex, that call has undefined behavior (assuming the mutex type is PTHREAD_MUTEX_NORMAL). I imagine that call is just never returning or something.
Note that your code has other problems handing the cleanup - if you execute the continue for the loop, you'll call pthread_cleanup_push() a second time (or more), which will add another cleanup context.
There may be other problems (I'm not very familiar with pthread_cancel()).

Bad file descriptor on pthread_detach

My pthread_detach calls fail with a "Bad file descriptor" error. The calls are in the destructor for my class and look like this -
if(pthread_detach(get_sensors) != 0)
printf("\ndetach on get_sensors failed with error %m", errno);
if(pthread_detach(get_real_velocity) != 0)
printf("\ndetach on get_real_velocity failed with error %m", errno);
I have only ever dealt with this error when using sockets. What could be causing this to happen in a pthread_detach call that I should look for? Or is it likely something in the thread callback that could be causing it? Just in case, the callbacks look like this -
void* Robot::get_real_velocity_thread(void* threadid) {
Robot* r = (Robot*)threadid;
r->get_real_velocity_thread_i();
}
inline void Robot::get_real_velocity_thread_i() {
while(1) {
usleep(14500);
sensor_packet temp = get_sensor_value(REQUESTED_VELOCITY);
real_velocity = temp.values[0];
if(temp.values[1] != -1)
real_velocity += temp.values[1];
} //end while
}
/*Callback for get sensors thread*/
void* Robot::get_sensors_thread(void* threadid) {
Robot* r = (Robot*)threadid;
r->get_sensors_thread_i();
} //END GETSENSORS_THREAD
inline void Robot::get_sensors_thread_i() {
while(1) {
usleep(14500);
if(sensorsstreaming) {
unsigned char receive;
int read = 0;
read = connection.PollComport(port, &receive, sizeof(unsigned char));
if((int)receive == 19) {
read = connection.PollComport(port, &receive, sizeof(unsigned char));
unsigned char rest[54];
read = connection.PollComport(port, rest, 54);
/* ***SET SENSOR VALUES*** */
//bump + wheel drop
sensor_values[0] = (int)rest[1];
sensor_values[1] = -1;
//wall
sensor_values[2] = (int)rest[2];
sensor_values[3] = -1;
...
...
lots more setting just like the two above
} //end if header == 19
} //end if sensors streaming
} //end while
} //END GET_SENSORS_THREAD_I
Thank you for any help.
The pthread_* functions return an error code; they do not set errno. (Well, they may of course, but not in any way that is documented.)
Your code should print the value returned by pthread_detach and print that.
Single Unix Spec documents two return values for this function: ESRCH (no thread by that ID was found) and EINVAL (the thread is not joinable).
Detaching threads in the destructor of an object seems silly. Firstly, if they are going to be detached eventually, why not just create them that way?
If there is any risk that the threads can use the object that is being destroyed, they need to be stopped, not detached. I.e. you somehow indicate to the threads that they should shut down, and then wait for them to reach some safe place after which they will not touch the object any more. pthread_join is useful for this.
Also, it is a little late to be doing that from the destructor. A destructor should only be run when the thread executing it is the only thread with a reference to that object. If threads are still using the object, then you're destroying it from under them.

Resources