synchronize a server-client program in c - c

In the code there are simultaneous operations between the clients and the server on the same datas. I used semaphores for synchronization. But it turns out that I had to add unsleep(5000) after each sem_post because the client performing the operation starts the next one directly without letting the others start. In the Code I would like to remove this unsleep.
How can I synchronize my threads without using unsleep at the end?
Client 1
while(condition){
sem_wait(&sem);
--operations--
sem_post(&sem)
unsleep(50000);
}
Client 2
while(condition){
sem_wait(&sem);
--operations--
sem_post(&sem)
unsleep(50000);
}
Client 3
while(condition){
sem_wait(&sem);
--operations--
sem_post(&sem)
unsleep(50000);
}

Related

Single thread blocks all other at WinSock recv()

I have a multi threaded program and every thread is something like:
thread() {
connect();
while(1) {
recv();
do_some_work();
}
}
If you exchange do_some_work() with sleep(5) to simulate a load which blocks the thread and stops it from reaching it's recv() call all the other threads block at recv() for the amount of time that thread sleep(). There is data received I can see it with WireShark and those are video streams so they never stop sending.
I wonder why is that thread blocking all other threads when WinSock(2,2) is supposed to be multi-threaded ?
EXPECTED BEHAVIOR: It should not block the other threads.
UPDATE: Seem like the server is blocking all it's clients when a single client doesn't read what is sent to it. I blame it on poor server design.
Seem like the server is blocking all it's clients when a single client doesn't read what is sent to it. I can guess that it's a single thread that manages all connections and send() blocks because it doesn't use select() or something along those lines.

Drawing with ncurses, sockets and fork

So I'm doing the barbershop problem but now I want to make it 'visual' and network-friendly. When the server starts up, awaits for clients to connect, each time a client connects it draws a 'P' that travels around the screen up to the barber position. I do this with NCurses and I have no problem with that.
However I only managed to draw one client (one 'P') at a time. I'd like to see many clients ('P's) in the screen. Because the way I have it now I only use 1 chair at a time, the client then gets attended and exits, then the next client in the accept() queue enters the screen and so on. It gives the impression that there is no actual concurrence thought there is.
I have a very extense code but the fork/socket part is here:
pid_t client;
int p;
RandSeed=8;
listen(connection,90);
while(1){
remote_dir_size = sizeof(remote_dir);
//"Awaiting connection...
if((connection_client=accept(connection,(struct sockaddr *)&remote_dir,&remote_dir_size))<0){
console_write("CONNECTION REJECTED!");
exit(-1);
}
//"Connection accepted!
client=fork();
switch(client)
{
case -1:
console_write("Error Forking!!");
exit(1);
case 0:
close(connection); //So that another client can come.
recvs = recv(connection_client,petition,sizeof(petition),0);
//console_write(petition);
// console_write(" moviendose.");
move_client();
//Check for avialable chairs
//waiting_client_count++;
sem_wait(waitingRoom); //wait until available
move_client_to_chairs();
sitting_client_count++;
redraw_chairs(); //redraw chair <--Useless since only 1 chair is used at a time :/
//waiting for barber
sem_wait(barberChair);
//barber available, chair occupied is now free
sem_post(waitingRoom);
sitting_client_count--;
redraw_chairs();
move_client_to_barber(); //Move 'P' towards barber chair
sit_client_barber();
//Wake barber
sem_post(barberPillow);
//Wait until barber ends
sem_wait(seatBelt);
//release chair
sem_post(barberChair);
exit_client();
exit(0);
default:
//barber sleeps until someone wakes him
sem_wait(barberPillow);
randwait(5);
//barber cutting hair
randwait(5);
//barber finished
//free client
sem_post(seatBelt);
wait(&p);
}
}
Complete version of the code is here
My problem is:
Server starts up good. Then when I run a ./client the server screen starts drawing the P along the screen and it moves it correctly, the client gets its haircut and exits. But when I run 2 or more ./clients the server screen draws the process once at a time, there's only one client at a time inside the barbershop; as if it's waiting for that one client to exit() in order to start the next forked process.
I find this very odd, what am I missing here? Is it a problem of accept queue? Should I try a different perspective?
The problem is that your parent process is trying to do two different things that need waiting:
"barber sleeps until someone wakes him"
accept()
Without some kind of joint waiting, this architecture does not work. Both pieces of code sleeps waiting for a single kind of event, disregarding the other type of event. For example, when a client comes in, the program will not accept another client until "barber finished".
There are two directions to solve the problem:
Join the two kinds of waiting: for accept(), you can turn the socket into non-blocking mode, and use select() or poll() to wait until an event comes in, for the semaphore, this is not so trivial, but if you open a socket between the parent and each child, and turn the semaphore handling into network communications, you can have a single select() or poll() waiting for all the sockets (one for receiving new client connections, and one per client for communicating with them) at a single place. You'd also have to redesign the semaphore handling - and get rid of the sleep there, something like keeping a list of active timers, and go back to select() or poll() until the next timer times out (their last parameter can put a limit on the maximum wait time).
Separate the accept() and the semaphore handling into two
processes, ie the parent is handling the new incoming connections,
and a child process "simulates" the barber. Actually, the way you
tried to implement the "barber", you'd need one child process per
barber, because the process is sleeping while simulating the job
done by the barber. Or you redesign the "barber" simulation as mentioned in the first part.

Condition Vars at POSIX

I am making a theatre - reservation application for a project. My theatre contains 10 operators, so everytime only 10 clients can make reservations simultaneously. When a client is done, another one is connected with an operator.
I have a server-client connection established. Everytime a new client appears i am creating a new thread. Now my problem is how to make 10 threads do their operation simultaneously. I know that i have to use condition vars but do not know how exactly.
What are my thoughts, whenever a client connects
lock mutex()
counter++;
if(counter > 10)
block thread() until an operator is free
else
do computations
unlock mutex()
I know i have to use cond_signal and cond_wait but i don't know how exactly. Any help?
Before calling the threads:
sem_t *sem;
sem = (sem_t*)malloc(sizeof(sem_t));
sem_init(sem, 0, 10);
Inside the threads:
sem_wait(sem);
do computations
sem_post(sem);
The last parameter of sem_init is how many threads will be allowed to be executed.
Every time you call sem_wait that value is decreased and if it becomes <0 the thread is paused until it becomes again positive.
when you call sem_post that value is increased by 1 and a new thread can execute the inner code.

multithread server doesn't continue to execute whenever a client get disconnected

hi there i'm working on a multithread Server (TCP) in C and i have a little issue about it. Everything works fine, more than one thread can connect to the server but whenever a client writes "exit" (which is a condition for a client when he/she writes "exit" string he/she goes to disconnect from the server) serves shutsdown itself also. So the communication through other threads get lost. However, logically it should be waiting for other clients even some current clients get disconnected. Here is a part of main and server is in a endless loop for waiting clients. hsock is id of socket belongs to server and csock is the id of clients.
main(){
.
.
.
while(1){
if(counter==0)
printf("waiting for a connection\n");
csock = (int*)malloc(sizeof(int));
if((*csock = accept( hsock, (struct sockaddr*)&sadr, &addr_size))!= -1){
printf("---------------------\nReceived connection from %s\n",inet_ntoa(sadr.sin_addr));
pthread_create(&thread_id,0,&SocketHandler, (void*)csock );
counter++;
}
else{
fprintf(stderr, "Error accepting %d\n", errno);
}
}// end while
.
.
.
return 0
}
As you can see whenever a client get disconnected, server should keep waiting for an another threads. On the other hand, this is the last part of SocketHandler function which is a thread function.
void* SocketHandler(void* csock){
.
.
.
printf("Client disconnected\n");
free(csock);
return 0;
}
After return 0 statement isn't it necessary to return back to while(1) loop in main. I will be glad if you can help and thanks anyway
Threads run asynchronously once created, which means that the main thread (the one doing the accept) should continue looping and be back to accepting new connections, whatever the child thread does.
Some advices:
if your thread can run autonomously, use pthread_detach after the create to let thread handle its own termination graciously.
don't forget to do a close(csock) before ending the thread.
you don't necessarily need to allocate the int which will contain the socket descriptor, just pass it as the void * directly (but I guess that you will be passing more information than just the socket in a structure in a future version of your code).
After return 0 statement isn't it necessary to return back to while(1)
loop in main.
No. The thread exits. It has nothing to so with what happens in other threads.
I don't see how you can expect anybody to help you with a networking problem that happens on client disconnect when you don't show any code that handles the networking to the client.

Linux Kernel: Wait for other threads to complete

I have a linux kernel module, I had to implement a TCP server and multiple clients to send some traffic. I had a question,
Now at the server end, I have a main-kthread which spawns another kthread once it sees a TCP connection waiting to be Accepted. Now after the main kthread spawns say a couple of kthreads how can I put the main-kthread in wait state to make sure the other kthreads exit before the main-kthread can exit.
I am looking something similar to phtread-join semantics, but i need this in the Linux kernel space.
I could not find kthread_join as such, I am looking at alternatives. I did read about waitqueues. Hence was looking at interruptible_sleep_on() and wake_up().
But am unable to figure out how to use these API's.
For example,
In the main-thread, I do a interruptible_sleep_on, then who should wake him up? All the other threads, or the last thread? how do i figure who is the last thread exiting? Also how to make sure, the other threads have exited when this main-kthread is woken up.
Wait queues are the right tools. There is a good description in Linux Device Drivers (LDD) chapter 6. Here's a sketch of how your code might look like:
Maintain a counter of server threads.
Increment the counter just before spawning a server thread.
When the server thread exists, decrease the counter.
In the main thread, when exiting, wait on a wait queue until the counter value is 0.
In the server threads, just after decreasing the counter, notify the main thread by signaling on the wait queue.
Warning: untested code, this is just a skeleton.
struct global_data {
wait_queue_head_t wq;
atomic_t thread_count;
};
main_thread () {
global_data gd = {0};
init_wait_queue_head(&gd.wq);
while (serving) {
…
atomic_inc(&server_threads);
if (IS_ERR_OR_NULL(kthread_create(server_thread, &gd)) {
atomic_dec(&server_threads);
}
}
wait_event_interruptible(&gd.wq, atomic_read(gd.thread_count) == 0);
/* final cleanup */
}
server_thread (global_data *gd) {
…
atomic_dec(&gd->server_threads);
wake_up(&gd->wq);
}

Resources