【发布时间】:2016-03-10 02:35:40
【问题描述】:
我需要帮助让mutex 以我想要的方式工作。我正在制作一个带有服务器和多个客户端的简单银行系统。
服务器有两个线程。一个线程监听连接。第二个线程是在客户端连接到服务器时创建的。
客户端有 3 个线程。有主线程使其他两个线程。第二个线程只是从服务器接收消息并输出它们。第三个线程只接受输入并将它们发送到服务器。
我在客户登录后尝试在客户会话中使用mutex。例如,如果一个客户使用他们的帐户登录服务器,我想用mutex 锁定该帐户会话。因此,如果任何其他客户端尝试登录同一个帐户,他们将不得不等待已经登录的客户端。
上述场景与我的代码完美配合。我目前遇到的问题是多个帐户。假设 client1 登录到他们的帐户并开始做事。然后 client2 尝试登录到不同于 client1 的帐户。由于 client1 帐户上 mutex 中的 lock,它不会让 client2 进入。
我想这样做,如果 client1 登录到他们的帐户,在 client1 完成之前,其他客户都不能登录到 client1 的帐户。不过,其他客户端应该能够登录其他帐户并对其进行单独锁定。
这是我的服务器代码(lock 在 curr_acc() 中):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <unistd.h>
#include <pthread.h>
// Mutex var
pthread_mutex_t lock;
int main(int argc, char *argv[])
{
pthread_mutex_init(&lock, NULL);
server_listen();
pthread_mutex_destroy(&lock);
return 0;
}
int server_listen()
{
int socket_desc, client_sock, c, *new_sock;
int portno = 8888;
struct sockaddr_in server, client;
socket_desc = socket(AF_INET, SOCK_STREAM, 0);
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
server.sin_port = htons(portno);
bind(socket_desc, (struct sockaddr *) &server, sizeof(server))
listen(socket_desc, 5);
c = sizeof(struct sockaddr_in);
// Accept connection
while((client_sock = accept(socket_desc, (struct sockaddr *) &client, (socklen_t *) &c)))
{
// Create new thread and sock
pthread_t sniffer_thread;
new_sock = malloc(1);
*new_sock = client_sock;
pthread_create(&sniffer_thread, NULL, handle_client, (void *) new_sock)
}
}
void *handle_client(void *new_sock)
{
// Convert void
int sock = *((int *) new_sock);
// Prepare to receive and send
int read_size, index;
char *msg = malloc(10);
while(recv(sock, msg, 10, 0) > 0)
{
if(strcmp(msg, "open") == 0)
new_acc(sock);
else if(strcmp(msg, "start") == 0)
curr_acc(sock);
else
write(sock, "Invalid input", 25);
memset(msg, 0, sizeof(msg));
}
free(new_sock);
free(msg);
// Exit the thread
pthread_exit(0);
}
void curr_acc(int sock)
{
int lock_ret;
// Get account name here and check if it's in array of accounts.
// Then try below
// Try and lock the thread then go inside
lock_ret = pthread_mutex_trylock(&lock);
if(!lock_ret)
{
// Show customer menu
write(sock, "\n Welcome!", 20);
cus_menu(sock);
// Unlock the thread
lock_ret = pthread_mutex_unlock(&lock);
}
else
{
printf("Cannot open account");
write(sock, "Cannot open account. Try again or wait...", 50);
}
}
这是我的服务器的精简版,但应该足以理解我在做什么。如果您想要更多,请告诉我。
我的客户端向服务器发送一个char 指针以检查输入。如果您需要查看客户端代码,也请告诉我。但如上所述,它非常简单。
任何帮助将不胜感激。我真的很想更好地理解mutex。谢谢!
【问题讨论】:
标签: c multithreading server pthreads mutex