Я пишу простой сервер котировок на C и работаю на Linux. Он должен выбрать случайную цитату из текстового файла и затем запустить две темы:
- первая отвечает за прием входящих соединений и отвечает выбранной цитатой,
- вторая должна проверяйте раз в час, прошел ли день. Если он обнаруживает, что начался новый день, он должен случайно выбрать другую цитату.
Моя проблема в том, что, хотя поток соединения работает нормально, другой даже не запускается.
Чтобы подтвердить это, я попытался добавить отладочную печать прямо в начале функции, выполняемой потоком, а другую - в то время как l oop, и ни одна из них не печатается (они удалены из кода, показанного здесь).
Я также добавил некоторый код для проверки возвращаемого значения pthread_create()
, скопированного со страницы руководства, но я не уверен, работает ли оно на самом деле, поскольку не обнаруживает никаких ошибок.
У меня есть привязан к тому, чтобы сначала запустить «поток таймера» и вообще не запускать поток соединения, но он все равно не выполняется. Ниже приведен соответствующий код, полный исходный код вы можете найти на GitHub :
#include <unistd.h>
#include <stdio.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <time.h>
#include <stdbool.h>
#include <pthread.h>
#include <errno.h>
#define handle_error_en(en, msg) \
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
pthread_mutex_t quoteLock=PTHREAD_MUTEX_INITIALIZER;
pthread_t checkForNewDayThread, connectionHandlerThread;
void * timer_thread_code(){ //The thread will act as a timer checking every hour if a day has passed
while (true) {
sleep(3600);
if (a_day_has_passed()) {
pthread_mutex_lock("eLock);
QOTD = read_random_quote_from_file(pathToQOTDfile);
pthread_mutex_unlock("eLock);
}
}
}
void * connection_thread_code(int port){ //Code for the thread to handle connections
struct sockaddr_in address;
int server_fd, new_socket, opt = 1, addrlen = sizeof(address);
// Creating socket file descriptor
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket failed");
exit(EXIT_FAILURE);
}
// Forcefully attaching socket to the port 1717
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))==-1)
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons( port );
// Forcefully attaching socket to the port 1717
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))<0)
{
perror("bind failed");
exit(EXIT_FAILURE);
}
if (listen(server_fd, 100) < 0)
{
perror("listen");
exit(EXIT_FAILURE);
}
printf("Listening on port %i\n", port);
while(1) { //connection handler loop
if ((new_socket = accept(server_fd, (struct sockaddr *) &address, (socklen_t *) &addrlen)) < 0) {
perror("accept");
exit(EXIT_FAILURE);
}
pthread_mutex_lock("eLock);
send(new_socket, QOTD, strlen(QOTD), 0);
pthread_mutex_unlock("eLock);
close(new_socket);
}
}
int main(int argc, char const *argv[])
{
int thread1, thread2, join;
thread1=pthread_create(&connectionHandlerThread, NULL, connection_thread_code(port), NULL);
if(thread1!=0) handle_error_en(thread1, "pthread_create");
thread2=pthread_create(&checkForNewDayThread, NULL, timer_thread_code(), NULL);
if(thread2!=0) handle_error_en(thread2, "pthread_create");
join=pthread_join(connectionHandlerThread, NULL);
if(join!=0) handle_error_en(join, "pthread_join");
return 0;
}
Примечание: я поставил только один pthread_join()
, потому что оба потока должны работать вечно, чтобы предотвратить возврат от основного должно хватить только одного из двух.
Заранее спасибо всем, кто мне помогает