standard Unix/Windows

standard Unix/Windows
Adamos19
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 2 lata
  • Postów:293
0

Natknąłem się na taki problem ostatnio. Mianowicie chciałbym zbudować taką sobie aplikację sieciową i potrzebuję wykorzystać do tego celu bibliotekę <winsock.h>, jednakże ona nie załatwia mi wszystkiego ponieważ brakuje w niej różnych definicji np. definicji np. ifr_addr.
Mam kompilator MinGW i wygląda na to że to nie zapewnia mi dostępności wszystkich bibliotek.

Próbowałem na żądanie wkopiowywać te biblioteki (zaciągam z neta i wklejam do odpowiedniego katalogu) ale jest to karkołomne gdyż zazwyczaj zaciągnięta i wgrana biblioteka korzysta z innej lub nawet wielu innych i drzewko się rozbudowuje...

Wiem że jest coś takiego jak standard Posix i że jest coś takiego jak kompilator CygWin który ten standard zapewnia i tam są wszystkie te biblioteki obecne. Ale czy to znaczy że nie da się tego zrobić z użyciem MinGW ?

Mimo to zrobiłem tak:
Zainstalowałem tego CygWin, uruchomiłem Eclipse i utworzyłem nowy projekt ale wybrałem kompilator CygWin zamiast MinGW.
Sprawdziłem w folderze c:\cygwin64\usr\include obecność bibliotek - oczywiście się tam znajdują, pomimo tego wywala błąd że nie ma takiej biblioteki.
Tak jakby szukał nie tam gdzie potrzeba. Nie wiem gdzie tkwi błąd na skutek czego nie wiem jak go naprawić.
Pomocy.

edytowany 1x, ostatnio: Adamos19
RE
  • Rejestracja:ponad 18 lat
  • Ostatnio:około 2 godziny
1

ehh pewne pomieszanie z poplątaniem, nie wiesz co jest czym:
cygwin
POSIX
Chcesz używać winapi a aby to zrobić używasz narzędzi unixowych? To się nie dodaje za bardzo.

Twoim rozwiązaniem jest:
a)kompilator microsoftu(czyli producenta windows)
b) przejście na coś więcej niż winapi np. framework qt.


We are the 4p. Existence, as you know it, is over. We will add your biological and technological distinctiveness to our own. Resistance is futile
Adamos19
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 2 lata
  • Postów:293
0

No tak...
Ale przecież po to instalowałem tego CygWin'a żeby móc pod Windowsem używać funkcjonalności standardu POSIX/UNIX, to przecież z tego co mi wiadomo jedno z zastosowań pakietu CygWin... czyż nie?
I wszystko byłoby dobrze gdyby w nowym projekcie utworzonym w eclipse na bazie kompilatora cygwin dało się zaciągnąć biblioteki które nota bene są obecne w odpowiednich folderach tego całego cygwina. W projekcie jednak odwołując się do tych bibliotek wyskakuje błąd że "no such file or directory" w kontekście danego pliku nagłówkowego.
Pomóżcie mi znaleźć przyczynę...

Zobacz pozostałe 4 komentarze
RE
-lws2_32 podałem to ponieważ to ci powinno umożliwić podpięcie tego winsock. Wiesz generalnie jak znasz gcc z linuksa no to standardowo wiesz że coś tam mając w katalogach jak sobie nie dodasz np. -lpthread to z użyciem będziesz miał problemy. A msvc to kompilator od ms. Zazwyczaj jak się robi porty na windows to się używa msvc. Robienie apek na windows przez cygwin i używanie Posix jest trochę moim zdaniem ryzykowne chyba że to apka na jakiś serwer.
Adamos19
Własnie po pierwsze nigdy wcześniej nie miałem do czynienia z linuxem a zawsze tworząc aplikacje konsolowe bazowałem na kompilatorze mingw-gcc.exe i środowisku eclipse. Podpięcie winsock jest możliwe ale nie jest możliwe podpięcie tych bibliotek pozostałych (np.ifaddrs.h). Co to jest to -lpthread ?? Dlaczego wg Ciebie robienie apek na windowsa przy użyciu cygwin i standardu posix jest ryzykowne ?
Adamos19
Ponawiam jednak pytanie: dlaczego jak robię projekt przy użyciu kompilatora cygwin-gcc to wówczas nie mogę zaimportować bibliotek które nota bene są obecne w folderze cygwina (c:\cygwin64\usr\include) , np. chodzi o bibliotekę ifaddrs.h ??
RE
Czyli w skrócie, masz windowsa na którego ładujesz port(lepszy lub gorszy) POSIX żeby używać linuksowych narzędzi ale nigdy nie używałeś gcc/linuksa, nie wiesz jak działa kompilator itd. Stary powiem mocne słowo parodia. O to co masz zrobić żeby sobie i nam oszczędzić czas. Napisze to za chwilę w osobnym poście.
RE
dlaczego używanie cygwin na windows to pomyłka? Chyba dlatego że masz linuksa i POSIX to obce środowisko na windows....
RE
  • Rejestracja:ponad 18 lat
  • Ostatnio:około 2 godziny
0

Wygląda mi na to że zaczynasz dopiero swoją przygodę z programowaniem.
Po pierwsze, wybór środowiska i narzędzi. Nie mam pojęcia co chcesz napisać ale wybierasz środowisko:

  • Windows -> najlepiej użyć visual studio c++(jest wersja darmowa) [LINK](https://msdn.microsoft.com/pl-pl/library/jj620919.aspx
  • Linux -> gcc/clang(najlpeiej zacznij od gcc) i to w sumie tyle(ide to sprawa drugorzędna)
    Następnie odpowiednio dobierasz biblioteki do zadania i je wrzucasz. Ogólnie polecam poczytać o Cmake jako systemie budowania.

Generalnie powyższe pkt. rozwiążą twoje problemy. Daruj sobie cygwin na windows bo pisanie od zera jakiś swoich programików i używanie do tego cygwin na windows to delikatnie mówiąc pomyłka.


We are the 4p. Existence, as you know it, is over. We will add your biological and technological distinctiveness to our own. Resistance is futile
Adamos19
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 2 lata
  • Postów:293
0

Pracuję w systemie win7.
Używam Eclipse i mam zainstalowane MinGW64bit i zbudowałem już nie jedną aplikację konsolową.
Aktualnie pracuję nad czymś takim jak konsolowe gadu gadu. To co wpisze po jednej stronie ma wyskakiwać po drugiej i odwrotnie.
Model ten chciałbym realizować po tcpip a do tego wszystkiego potrzebuję pewnych bibliotek np. ifaddrs.h które niestety ten mingw mi nie daje.
Wiem jednak że różne rzeczy np. gniazdka (socket) są dostępne w standardowym winapi dlatego też podciągnąłem bibliotekę winsock2.h.
Nie rozwiązuje to jednak mojego problemu bo w tej bibliotece nie ma np. zdefiniowanej struktury ifr_addr którą bym potrzebował do napisania mojej aplikacji.

RE
a) jaki masz problem użyć czegoś innego niż winapi ? b) jaki masz problem użyć maszyny wirtualnej z linuksem c) chcesz używać linuksowego środowiska w windows(po co) nie mając o nim pojęcia? d) jaki masz problem z wpisaniem w google "c++ network library" i "c++ tcpip library" ?
KL
  • Rejestracja:ponad 7 lat
  • Ostatnio:4 miesiące
  • Postów:191
0

To tak względem odniesienia się do komentarza kolegi i poprzednich wypowiedzi.

Wydaje mi się, że najsensowniejsze(ale jednocześnie bardziej wymagające) będzie zrobienie serwera pod daną platformę oraz klienta/klienty pod (inne?) poszczególne platformy, które chcesz obsługiwać.
Wtedy musisz jedynie wystawić API serwera dla klientów i jest załatwione, możesz pisać "elementy" aplikacji używając narzędzi, które są łatwo dostępne pod daną platformą.
Co prawda Cpp jest przenośny, ale jednocześnie zahacza na tyle nisko, że często korzysta z rozwiązań specyficznych dla danego systemu i potem jest kopa, jak czegoś potrzebujesz, czego akurat nie ma, a nie możesz znaleźć alternatywy.

Może opisz dokładniej jakie są wymagania względem aplikacji, to uda się wymyślić bardziej logiczne i globalne rozwiązanie problemu, które pociągniesz dalej sam? Bo na razie to wygląda na szukanie na siłę znanych sobie rozwiązań poza natywną platformą i stąd rodzą się problemy?

Przy czym... Mogę gadać kompletne głupoty, bo C++ znam na poziomie najwyżej zajęć uczelnianych, nigdy w nim głębiej nie grzebałem, to też trudno coś sensownego wymyślić w tym konkretnym przypadku. Ale są bardziej kompetentni technologicznie koledzy, więc na pewno cosik się ogarnie :)

vpiotr
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
3

Masz kilka opcji:

  • Win32 API na Windows, POSIX na Linux
  • POSIX na Windows przez Cygwin, POSIX na Linux
  • Windows Subsystem for Linux na Windows, POSIX na Linux

MinGW nie dostarcza żadnego standardowego API, jest po prostu portem GCC i przyległości.
Jak ustawić projekt dla WSL pod VS: https://blogs.msdn.microsoft.com/vcblog/2017/02/08/targeting-windows-subsystem-for-linux-from-visual-studio/

RE
a nie lepiej użyć po prostu czegoś typu boost.asio czy network z qt? Autor zwyczajnie chce użyć cygwin bo nie wie że są inne biblioteki do networkingu chyba.
Adamos19
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 2 lata
  • Postów:293
0

Wybieram POSIX na Windows przez Cygwin.
Mam prośbę do wszystkich. Proszę od tego momentu traktować moje pytania z wyłączeniem tego co pisałem powyżej pomimo tego że będą ciągle odnosić się do tego samego problemu.

Problemem jest aktualnie:
zainstalowałem cygwina z interesującymi pakietami bibliotecznymi, mam utworzony nowy projekt który kompiluje się z użyciem narzędzi cygwina
jestem również pewien że biblioteka <ifaddrs.h> znajduje się w folderze cygwin64\usr\include a pomimo tego kompilator twierdzi że jej tam nie ma.
Wiem że mam coś najprawdopodobniej pochrzanione z ustawieniami bo to przecież niemożliwe aby tego nie widział, pomożecie?

Adamos19
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 2 lata
  • Postów:293
0

Wybieram POSIX na Windows przez Cygwin i wiem że to niezgodne ze sztuką (no bo przecież po co stosować w aplikacji na windowsa interfejs POSIXowy jeśli można winapi) jak mówili przedmówcy ale potraktujcie moje zapytanie czysto teoretycznie i bardzo proszę nie dawajcie już takich komentarzy że jestem du... itd.

Mam prośbę do wszystkich. Proszę od tego momentu traktować moje pytania z wyłączeniem tego co pisałem powyżej pomimo tego że będą ciągle odnosić się do tego samego problemu.

Problemem jest aktualnie:
zainstalowałem cygwina z interesującymi pakietami bibliotecznymi, mam utworzony nowy projekt który kompiluje się z użyciem narzędzi cygwina
jestem również pewien że biblioteka <ifaddrs.h> znajduje się w folderze cygwin64\usr\include a pomimo tego kompilator twierdzi że jej tam nie ma.
Wiem że mam coś najprawdopodobniej pochrzanione z ustawieniami bo to przecież niemożliwe aby tego nie widział, pomożecie?

edytowany 2x, ostatnio: Adamos19
Adamos19
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 2 lata
  • Postów:293
0

Ustaliłem następującą rzecz.
Kompilator cygwin znajdujący się w:
c:\cygwin64\bin\x86_64-w64-mingw32-gcc.exe
szuka wszystkich bibliotek jedynie w folderze:
C:\cygwin64\usr\x86_64-w64-mingw32\sys-root\mingw\include
podczas gdy interesujące mnie bibiloteki są nie tylko tutaj (bo tutaj też są niektóre np.stdio.h, conio.h) ale także i tutaj:
c:\cygwin64\usr\include
Jak tego dziada zmusić do tego żeby szukał także i w innych swoich folderach ???

W zasadzie to ustaliłem jeszcze że np.stdio.h i conio.h są nie tylko tu:
C:\cygwin64\usr\x86_64-w64-mingw32\sys-root\mingw\include
ale i tutaj:
c:\cygwin64\usr\include
tak więc rozwiązaniem byłoby zmuszenie tego cygwina do tego aby szukał ich tylko tutaj:
c:\cygwin64\usr\include
Załatwiłoby to kompletnie sprawę. Ponawiam pytanie: jak zmusić go do tego???

edytowany 1x, ostatnio: Adamos19
Zobacz pozostałe 7 komentarzy
RE
Dodam do tego że buildy na windowsa robi się raczej na msvc niż na niedorobionym mingw.
Adamos19
Ale jak to zmuszam... przecież plikiem wynikowym jest plik .exe który jest plikiem wykonywalnym windowsa. Po drugie: co to jest "biblioteka do sieci"? i co to jest "distrach"?
elwis
Generalnie cygwin wymaga dodania dllki cygwina, która do lekkich nie należy. Niemniej jednak cygwin choć pewnie ma przestarzały soft jest bardzo przydatnym narzędziem. Poza tym nie czepiajcie się tak. Gość się uczy. Distro -> dystrybucja Linuksa (system operacyjny oparty o to jądro)
RE
.dll cygwina to zależności od niego. Serio wyznacznikiem jest dla ciebie wygenerowanie .exe? Nie bez powodu kod aplikacji mulitiplatformowych jest budowany natywnymi narzędziami a nie protezami jak cygwin. Nie ty pierwszy wpadłeś na pomysł aplikacji sieciowej, i masz biblioteki które udostępniające pewne API sieciowe i jest ono takie samo(lub prawie) na windows i linuks np. w framework qt, boost czy inne. Cygwin może i jest przydatny ale używanie go tylko dlatego że winsocket nie ma jakiejś struktury?
elwis
@revcorey: A powód „bo to już znam” cię nie przekonuje? Moim zdaniem to bardzo mocny argument. Z resztą chyba widzisz, że @Adamos19 chce popełnić ten błąd. Niech popełni, jak zabraknie mu nowego C++ lub wydajności poszuka innego rozwiązania. Tak się uczą niektórzy ludzie. :)
elwis
  • Rejestracja:ponad 18 lat
  • Ostatnio:12 dni
0

winsock to implementacja microsoftowa socketów, które są koncepcją z uniksa. Żeby skompilować cokolwiek pod mingw/cygwinem raczej szukaj materiałów pod Linuksa. Na przykład tu masz prosty serwer http: https://github.com/ankushagarwal/nweb . Taki kod powinien się skompilować w tym środowisku.
http://www.linuxhowtos.org/C_C++/socket.htm - tu masz dokładniejszy opis socketów. To jest standard POSIX, ale myślę, że słowo kluczowe „Linux” da lepsze rezultaty w wyszukiwarce.


edytowany 1x, ostatnio: elwis
Adamos19
Mam napisany aplikacje serwerową i kliencką w standardzie posix ale nie potrafię skompilować bo mi nie widzi cygwin bibliotek które nota bene posiada w swoich folderach... proszę, pomóżcie mi tylko w tym o czym piszę.
elwis
znajdź i wklej linię poleceń dla kompilatora i linkera, obstawiałbym, że jeśli nie widzi nagłówków to dlatego, że ma ustawiony standard C/C++ w którym nie ma tego, jeśli brakuje samej biblioteki, pewnie trzeba ją dopisać do linii poleceń.
Adamos19
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 2 lata
  • Postów:293
0

Panowie napisałem coś takiego:

Kopiuj
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ifaddrs.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <pthread.h>
#include <termios.h>

/* deklaracja statycznych struktur potrzebnych do obslugi terminala (funkcja _getch) */
static struct termios old, new;

/* funkcja inicjalizujaca ustawienia terminala i/o */
void initTermios(int echo)
{
    /* przechwycenie starych ustawien terminala i/o */
    tcgetattr(0, &old);

    /* ustawienie nowych ustawien takich jak stare */
    new = old;

    /* wylaczenie buforowania i/o */
    new.c_lflag &= ~ICANON;

    /* ustawienie trybu echa */
    new.c_lflag &= echo ? ECHO : ~ECHO;

    /* uzycie nowych ustawien terminala i/o */
    tcsetattr(0, TCSANOW, &new);
}

/* funkcja przywracajaca poprzednie ustawienia terminala i/o */
void resetTermios(void)
{
  tcsetattr(0, TCSANOW, &old);
}

/* funkcja odczytujaca jeden znak - echo parametr (0-brak, 1-obecne echo) */
char getch_(int echo)
{
  char ch;
  initTermios(echo);
  ch = getchar();
  resetTermios();
  return ch;
}

/* funkcja odczytujaca pojedynczy znak (bez echa) */
char getch(void)
{
  return getch_(0);
}

/* funkcja odczytujaca pojedynczy znak (z echem) */
char getche(void)
{
  return getch_(1);
}

void * client_loop(void * arg)
{
    /* deklaracje zmiennych lokalnych */
    int sck = *((int *) arg);
    char buffer[1024];
    int rcvd, i;

    /* wieczna petla w watku */
    while (1)
    {
        /* odbior w locie danych */
        rcvd = recv(sck, buffer, 1024, 0);

        /* jesli odebrano przynajmniej jeden bajt */
        if (rcvd > 0)
        {
            /* wyswietlenie waznych danych z bufora */
            for (i = 0; i < rcvd; i++)
            {
                printf("%c", buffer[i]);
            }
        }
    }

    /* zakonczenie watku */
    pthread_exit(NULL);
}

/* glowna funkcja programu */
int main(int argc, char * argv[])
{
    /* deklaracje potrzebnych zmiennych uzywanych w programie serwera */
    int port, nFoo = 1, nBind, nListen, nClientSocket;
    struct sockaddr_in stAddr, stClientAddr;
    socklen_t nTmp;

    /* wypisanie komunikatow startowych */
    printf("Witaj w programie serwera!\n\n");
    printf("Wpisz port na ktorym serwer bedzie nasluchiwal polaczenia\nPort : ");

    /* odczyt numeru portu */
    scanf("%d", &port);

    /* zerowanie struktury adresowej */
    memset(&stAddr, 0, sizeof(struct sockaddr_in));

    /* wybor sieci : internetwork tcp lub udp */
    stAddr.sin_family = AF_INET;

    /* konwersja z reprezentacji lokalnej do sieciowej dla liczb 32 bitowych */
    /* i przypisanie do pola struktury adresowej */
    stAddr.sin_addr.s_addr = htonl(INADDR_ANY);

    /* konwersja z reprezentacji lokalnej do sieciowej dla liczb 16 bitowych */
    /* i przypisanie do pola struktury adresowej */
    stAddr.sin_port = htons(port);

    /* utworzenie gniazda */
    int nSocket = socket(AF_INET, SOCK_STREAM, 0);

    /* jesli nie udalo sie poprawnie utworzyc to dajemy komunikat i wychodzimy z programu */
    if (nSocket < 0)
    {
        fprintf(stderr, "%s: Can't create a socket.\n", argv[0]);
        exit(1);
    }

    /* ustawienie opcji gniazda na odpowiednie */
    setsockopt(nSocket, SOL_SOCKET, SO_REUSEADDR, (char *)&nFoo, sizeof(nFoo));

    /* laczenie powolanego do zycia gniazda oraz struktury adresowej - tzw.bindowanie */
    nBind = bind(nSocket, (struct sockaddr *)&stAddr, sizeof(struct sockaddr));

    /* jesli nie udalo sie poprawnie zbindowac to dajemy komunikat i wychodzimy z programu */
    if (nBind < 0)
    {
        fprintf(stderr, "%s: Can't bind a name to a socket.\n", argv[0]);
        exit(1);
    }

    /* rozpoczecie nasluchiwania serwera na wybranym porcie wraz z ustawieniem rozmiaru kolejki */
    nListen = listen(nSocket, 5);

    /* jesli nie udalo sie poprawnie rozpoczac nasluchu to dajemy komunikat i wychodzimy z programu */
    if (nListen < 0)
    {
        fprintf(stderr, "%s: Can't set queue size.\n", argv[0]);
        exit(1);
    }

    /* nieskonczona (wieczna) petla */
    while(1)
    {
        /* pozyskanie rozmiaru struktury */
        nTmp = sizeof(struct sockaddr);

        /* instrukcja blokujaca - program bedzie czekal az przyjdzie jakies żadanie polaczenia */
        nClientSocket = accept(nSocket, (struct sockaddr *)&stClientAddr, &nTmp);

        /* jesli nie udalo sie poprawnie przejsc przez powyzsza procedure to dajemy komunikat i wychodzimy */
        if (nClientSocket < 0)
        {
            fprintf(stderr, "%s: Can't create a connection's socket.\n", argv[0]);
            exit(1);
        }

        /* ta czesc programu bedzie wykonywana jesli żadanie polaczenia zostalo zrealizowane */
        /* wowczas piszemy komunikat skad takie żadanie przyszlo do nas (adres ip) */
        printf("[connection from %s] accepted\n", inet_ntoa((struct in_addr)stClientAddr.sin_addr));

        /* utworzenie dodatkowego watku - do odbierania danych nadawanych przez clienta */
        pthread_t id;
        pthread_create(&id, NULL, client_loop, nClientSocket);

        while(1)
        {
            char temp = getch();
            write(nClientSocket, &temp, 1);
        }

        close(nClientSocket);
    }

    return 0;
}

Operuję na kompilatorze GCC z cygwina a to znaczy że standard posix ma tutaj zastosowanie. Ja rozumiem że to może być niezgodne ze sztuką ale ja się uczę i pomimo to (jak zresztą powiedział @elwis któremu nota bene jestem wdzięczny że bierze mnie w obronę) prosiłbym o odpowiedzi.
Odpalam telnet który robi mi za klienta. Jak skasuję to:

Kopiuj
pthread_create(&id, NULL, client_loop, nClientSocket);

to normalnie w telnecie pokazuje mi się to co nadaję z tej aplikacji serwera. Natomiast jak już stworzę ten wątek (niewycięta linia kodu) to wówczas aplikacja się zamyka a telnet mówi o przerwanym połączeniu. Dlaczego tak się dzieje. Przecież w tym wątku dodatkowym nie ma nic co by mogło powodować nieprawidłowe działanie, no chyba że o czymś nie wiem. Pomóżcie please.
Mało tego, jak ta funkcja związana z wątkiem dodatkowym nie ma nic w sobie tylko wieczną pętlę załóżmy to telnet również informuje o tym że zerwano połączenie. Wygląda na to że coś pochrzaniłem z tym wątkiem dodatkowym ale co (przekazuję do niego tylko parametr który jest id socketa utworzonego ale już sam fakt takiego przekazania musi powodować wysypywanie się aplikacji - wątpię....) ???

edytowany 2x, ostatnio: Adamos19
Adamos19
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 2 lata
  • Postów:293
0

Dobra, nie było pytania. Brakowało ampersanda w przekazywaniu argumentu typu identyfikator socketa. Wszystko działa jak należy. Dzięki.

AL
  • Rejestracja:prawie 11 lat
  • Ostatnio:prawie 3 lata
  • Postów:1493
0

W C++ np. Boost ASIO byłoby 30x lepiej, bez zastanawiania się czy to POSIX, WinSock czy inny zwierz. Opcja druga, jak już musi być POSIX, ale może być C++: ACE Reactor to całkiem przyzwoity kod. Jak ma być czyste C, to nadal możesz użyć reaktora, Google: Adam Tornhill C reactor pattern. Ale na Boga, nie używaj gołych wątków.

Adamos19
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 2 lata
  • Postów:293
0

Czemu nie powinno się używać "gołych wątków" ?

RE
z tego samego powodu dla którego odradzałem ci używanie kombinatorstwa w postaci przyspawania się do cygwina na windowskie itd. Bo nie jest to przenośne to raz. Dwa te rozwiązania to niski poziom abstrakcji. Nie wynaleziono takich api jak openmp czy wątki z qt dla jaj. Są przenośne, łatwiejsze w użyciu a przez to bezpieczniejsze w użyciu co skutkuje mniejszą ilością błędów. Ale z jakiś powodów brniesz w te rozwiązania.
AL
  • Rejestracja:prawie 11 lat
  • Ostatnio:prawie 3 lata
  • Postów:1493
0

Może źle to sformułowałem: w tym przypadku gołe wątki to walenie do muchy z naprawdę sporego kalibru armaty, jednowątkowy reactor spokojnie sobie da radę. Jak już koniecznie chcesz jakoś to osobno obsługiwać to wieloprocesowość może być prostsza z uwagi na lepsze (imho) mechanizmy komunikacji, ale to nadal rusznica przeciwczołgowa (zamiast artylerii) na tego samego, niezbyt grubego zwierza.
W innych przypadkach nadal warto rozważyć np. Boost ASIO, bo zapewnia abstrakcję nad systemowymi wywołaniami do obsługi TCP/IP czy timerów (jest przenośne), poza tym pozwala uwolnić się od pilnowania wątków (no dobra, nie zawsze) na rzecz pisania faktycznego programu.
Generalnie wątki są złe, bo mało kto umie ich dobrze używać, a nawet wyjadaczom potrafi wątkowy „heisenbug” stanąć ością w gardle.

Adamos19
  • Rejestracja:ponad 10 lat
  • Ostatnio:około 2 lata
  • Postów:293
0

A możecie jeszcze napisać co to takiego ten jednowątkowy reactor? Co to w ogóle "reactor" ? Pierwszy raz słyszę to określenie...

edytowany 1x, ostatnio: Adamos19
AL
  • Rejestracja:prawie 11 lat
  • Ostatnio:prawie 3 lata
  • Postów:1493
0

Taki wzorzec projektowy. Podałem Ci czego w google’u szukać.

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)