Permalänk

Kodardilemma, ircbot [C++]

Jag arbetar på en ircbot med pluginstöd. Jag har kommit relativt långt måste jag säga. Den har varit igång några dagar på prov nu. Men för att kunna skriva alla plugins som jag skulle vilja så skulle jag behöva ha möjligheten att sätta en timer ifrån ett script som gör att en vald funktion ifrån scriptet anropas när timern är klar. Som det är nu använder jag "blocking" socket-funktioner eller vad det nu kallas, d.v.s. jag väntar tills jag får något från ircnätet. Programmet är alltså helt låst så länge det inte tar emot någon data, vilket är bra med tanke på att det inte utnyttjar någon processorkraft då. Det är dock inte lika bra om jag vill implementera timers, eftersom jag kanske missar en tid med någon/några minuter i värsta fall. Som jag ser det har jag 2 val.

1. Stanna inte och vänta på data från nätet. Då skulle jag kunna ha någon ifsats som kollar om tiden matchar någon begärd timer från ett script. Dock skulle det ju innebära att programmet är fullt aktivt konstant, vilket inte är speciellt bra.

2. Använda någon os-funktion för att sätta en timer och en callback-funktion eller liknande (har inte tittat på det så mycket). Detta skulle ju vara en bra lösning på problemet, dock antar jag att jag får hålla på med mutexar och liknande vilket jag inte är så hemma på. En annan sak som inte är så bra är att det blir plattformsberoende. Tanken är att jag ska porta boten till andra plattformar också så småningom, även om jag utvecklar den på Windows XP för tillfället.

Så, om någon har något annat förslag än de två jag kan komma på så är jag idel öra, annars vill jag gärna ha lite feedback på mitt resonemang så att jag kan bestämma mig.

Tack!

Permalänk

är inte windows posixkompatibelt nuförtiden? Isf kan du ju typ använda Posix XSI Interval Timers lr nått.

Permalänk
Hedersmedlem

busmissen: Sedan beror det på vilken kompilator man använder. Tror inte det finns någon kompilator till Windows (kanske MinGW) som har unistd.h och därmed usleep() exempelvis.

Dessutom fungerar trådar på olika sätt. Dock så är väl din kod inte så plattformsoberoende nu heller då du (antar jag) använder Winsock?

Visa signatur

Vim
Kinesis Classic Contoured (svart), Svorak (A5)
Medlem i signaturgruppen Vimzealoter.

Permalänk

Tack för svaren, fortsätt gärna.

Jo det stämmer att jag använder winsock, men det ser jag inte som något jättestort problem att koda om. Jag använder Dev-C++ med tillhörande kompilator förresten.

Men vi är alla överens om att det första alternativet går bort va? Inte särskilt kul att ha ett program av den här karaktären som drar en massa kräm i onödan.

Jag kollade lite på det där med Posix Interval Timers, men vad jag förstod så kunde jag bara få det att signalera via sigint när timern nådde noll, och där får man väl inga parametrar? Jag måste ju kunna stödja flera timers samtidigt. Olika scripts ska ju kunna använda någon form av set_timer()funktion oberoende av varandra. Så jag skulle behöva en variant där jag sätter en timer samt skickar en funktionspekare, som gör att timerhanteraren anropas vid rätt tillfälle, som i sin tur gör att rätt funktion i scriptet anropas.

edit: Vid närmare eftertanke kanske det inte är så dumt att ta det via sigint ändå.. jag ska fundera lite.

Permalänk

/* Returns true if socket is ready for reading within the timeout limit. */ static boolean wait_socket_readable(int sockfd, int timeout_secs) { fd_set fds_read; struct timeval timeout; timeout.tv_sec = timeout_secs; timeout.tv_usec = 0; FD_ZERO(&fds_read); FD_SET(sockfd, &fds_read); if (select(sockfd+1, &fds_read, NULL, NULL, &timeout) != -1) { if (FD_ISSET(sockfd, &fds_read)) return true; } return false; }

Om du inte vill pyssal med trådar eller signals, byt ut din blockerande "read" mot följande:

while (1) { if (wait_socket_readable(sockfd, 5)) read_from_network(...) check_timers() }

Inget du vill använda i din release version men det duger gott och väl för att få saker och ting att fungera.