[C] server, socket, thread-safeness of stdio.h functions


New Member

Messages: 2

I wrote a webserver in C under FreeBSD...

FILE* log_file;
// other data

fp = fopen(log_file);
// other inizializations
// create the thread pool
while(1) {
// 1) accept an incoming connection from a client;
// 2) assign the request to a free thread of the pre-allocated pool
// -) write the operations you do in the log_file and on stdout

THREADS of the pool BODY
// inizializations
while(1) {
// 1) handle a request assigned from main;
// -) write the operations you do in the log_file and on stdout

Now the questions:
i) The threads use the same file pointer (fp) to write in the log_file. Are there problems if more threads try to write using fprint() at the same time in the log_file? Are there precautions to take? Wich?

ii) Same question but for stdout using printf().

iii) Each thread of the pool has to open [fopen()], read [fread()] and close [fclose()] the file requested from the client before sending it. It could appen that 2 or more threads has to send the same file X to the clients so each thread will do fopen(), fread() and fclose() on the file X. Each thread will use for this operations its own file pointer. Are there precautions to take? Wich?

iv) My server can be terminated only by CTRL-C from the shell so it's not a clean exit because main is accepting connections, threads are handling requests, sockets and files are still open, dinamic memory is allocated...
Since a webserver should run for days or months continuosly and should be stopped quite never is it important to close it in a clean mode or is it only important that it works well when it's on? Which methods are usually used to communicate the server that it's time to end?

Sorry for all my qustions and many thanks to all who will be so kind to reply me. :)

Have a nice day!




Reaction score: 16
Messages: 58

glibc manual says that any operation on a stream (i.e. fprintf(), printf()) in multi-threaded apps can be in the same way as in single-threaded ones because POSIX requires that stream functions are atomic (implicit locking).
Have a look here

As for the program's termination, catch SIGINT. Write your signal handler and call exit() which closes all I/O streams (not file descriptors) or you can use a very useful function atexit(3)