Esta discussão foi arquivada. Não se pode acrescentar nenhum comentário. | | | Embora na minha opiniao nao ha' nada como ter o cuidado de usar apenas chamadas do sistema "reentrant" em vez de confiar isso a software que corre "on-the-fly". O Solaris tende a ter alternativas a chamadas "non-reentrant", mas outros sistemas operativos (e.g., Linux/glibc) nem sempre e por vezes a unica maneira de escreveres software portavel e' usares "wrappers" 'a volta de certas chamadas de sistema para teres a certeza que corre em plataformas multiplas sem grandes problemas. De uma maneira ou de outra, acho que "threads are evil" (TM) -- e sugiro esta leitura. echo '[dO%O+38%O+PO/d00]Fi22os0CC4BA64E418CE7l0xAP'|dc |
| | | | | A glibc também tem alternativas thread-safe. Basta compilar com gcc -D_REENTRANT (ou #define _REENTRANT) que o errno, gethostbyname, etc mudam para uma forma thread-safe. No que respeita à gtk, basta g_thread_init; g_threads_enter; g_threads_leave. Obviamente, algumas outras bibliotecas não se comportarão tão bem. "De uma maneira ou de outra, acho que "threads are evil" (TM) -- e sugiro esta leitura." Assim como é a OOP, assembly, whatever. Ou então, como tudo, depende do que se quer fazer, não? (Li o link. Não diz nada de jeito, critica o uso de threads em Unix, mas os exemplos de programação que dá são para win32, e finalmente, a partir de um projecto de controle de tapes/backups(?), e da sua ignorância relativamente a POSIX threads, conclui que Threads are Evil.)
hugs Strange |
| | | | A glibc também tem alternativas thread-safe. Basta compilar com gcc -D_REENTRANT (ou #define _REENTRANT) que o errno, gethostbyname, etc mudam para uma forma thread-safe. Eu nao disse que nao tinha -- disse que havia muitas chamadas de sistema que *nao* teem alternativa -- e muitas vezes apenas descobres que nao sao thread safe pela maneira dificil. Assim como é a OOP, assembly, whatever. Ou então, como tudo, depende do que se quer fazer, não? (Li o link. Não diz nada de jeito, critica o uso de threads em Unix, mas os exemplos de programação que dá são para win32, e finalmente, a partir de um projecto de controle de tapes/backups(?), e da sua ignorância relativamente a POSIX threads, conclui que Threads are Evil.) Hamm... de que forma e' que o seguinte nao e' verdade ? - Threaded programs are hard to debug.. Any thread can stomp on any other thread's memory, you have the problem of hanging locks, etc.
- It ain't Unix!. Unix is based upon the principle of "many small tools chained together".
- Killing threads sucks. This is part and parcel of the resource management problem.
Imagino que digas que ele nao conhece POSIX threads porque nao referiu mutex'es mas sim semaforos -- mas na realidade ambos sao praticamente a mesma coisa, excepto que semaforos sao "system wide" e nao "process wide". Threads sao muito bonitas quando o problema em mao e' simples de resolver, mas quando o problema a resolver e' complexo -- threads tornam-se extremamente dificil de gerir. Regards, echo '[dO%O+38%O+PO/d00]Fi22os0CC4BA64E418CE7l0xAP'|dc
|
| | | | Imagino que digas que ele nao conhece POSIX threads porque nao referiu mutex'es mas sim semaforos -- mas na realidade ambos sao praticamente a mesma coisa, excepto que semaforos sao "system wide" e nao "process wide". Os mutex só costumam ter dois estados. Os semáforos costumam suportar vários. Não tem nada a ver com o contexto. As threads POSIX definem apenas de mutex (naturalmente no contexto de cada processo já que estamos a falar de threads). Contudo, pode-se perfeitamente criar semáforos (também no contexto de cada processo). Os semáforos system wide que referiste imagino que sejam os de Sys V IPC. Threads sao muito bonitas quando o problema em mao e' simples de resolver, mas quando o problema a resolver e' complexo -- threads tornam-se extremamente dificil de gerir. As threads não são bonitas. São um facto da vida. Ter várias threads de execução todas dentro do mesmo contexo. Para o melhor e para o pior. Remember to be the Killer, not the Victim! (Nuklear Girl) |
| | | | * Threaded programs are hard to debug.. Any thread can stomp on any other thread's memory, you have the problem of hanging locks, etc. Concordo... # It ain't Unix!. Unix is based upon the principle of "many small tools chained together". Engraçado, também nessa premissa se basea a programação em paralelo, e a programação distribuída, às quais o modelo de threads pertence. * Killing threads sucks. This is part and parcel of the resource management problem. Porque quer alguém matar threads? A usabilidade de uma thread dependerá do que a thread faz, e então a própria thread saberá a melhor altura para terminar. (Ou termina-se o programa e todas as threads terminam.) " Imagino que digas que ele nao conhece POSIX threads porque nao referiu mutex'es mas sim semaforos -- mas na realidade ambos sao praticamente a mesma coisa, excepto que semaforos sao "system wide" e nao "process wide". Refiro que não conhece as threads POSIX por se referir a DLLs, semaphores, msdn.microsoft.com, TerminateThread, etc. Mas analisando ao pormenor: - resource management: o exemplo que dá é estúpido. Que tal um rnd = random_init()?
- kill(2)ar threads: existe o pthread_kill, que desconhece, e pode na mesma brincar com sinais.
- pthread_mutex tem um funcionamento ligeiramente diferente de semáforos, além de que também existem pthread_cond;
- "It encourages monolithic programs": perdão? Eu pensava que o objectivo de usar threads era *separar* partes independentes do programa...
- "It ain't Unix!. ... up until the day that the X window system came around and ruined it": não acredito que o X tenha arruinado o Unix ou o seu modelo, tanto mais que actualmente muitos criticam o l&f não ser uniforme pelo X não ter obrigado a um l&f e wm; assim como criticam ser orientado à rede...
" Threads sao muito bonitas quando o problema em mao e' simples de resolver, mas quando o problema a resolver e' complexo -- threads tornam-se extremamente dificil de gerir." Tudo depende do problema, mas, por exemplo, o que te parece mais simples: um servidor que arranca uma nova thread para resolver um pedido e esquece-a; um servidor que usa poll(2) ou select(2) e ou é monolítico ou guarda callbacks; ou um servidor que usa AIO? E é preciso notar que o segundo está sujeito a bloqueios no IO de que é necessário se precaver. Claro, threads não é uma panaceia e não é para ser usado indiscriminadamente como aconteceu com o Java. Mas agora chegamos ao cúmulo de ter um processo a demorar 3 horas porque o segundo processador fica apenas ocupado a fazer o refresh do ecrã, e isto porque quem o programou não se deu ao trabalho de usar threads.
hugs Strange |
| | | | Sem querer extender muito isto, mas a discussao esta' a ficar interessante e estou a gostar ;-) Engraçado, também nessa premissa se basea a programação em paralelo, e a programação distribuída, às quais o modelo de threads pertence. Nao e' bem assim -- "threads" baseiam-se num modelo monolitico (i.e., um processo com varias linhas de processamento) embora com concorrencia dentro do contexto. i.e., um agente que distribui o trabalho por varios sub-agentes que ainda dependem do agente principal -- um exemplo (na minha opiniao) ilustrativo de porque "multi-threading" nao e' realmente ideal (nota, mas por vezes a unica solucao) e' o facto de teres concorrencia *mas* uma heap partilhada. Refiro que não conhece as threads POSIX por se referir a DLLs, semaphores, msdn.microsoft.com, TerminateThread, etc. Tens que concordar que isso nao e' conclusivo -- alem de que o modelo POSIX nao e' assim tao diferente do modelo Win32 -- apenas teem interfaces diferentes. kill(2)ar threads: existe o pthread_kill, que desconhece, e pode na mesma brincar com sinais. Desculpa se parecer arrogante -- mas ja' experimentaste misturar sinais UNIX com threads ? E' terrivelmente dificil de gerir, e se usares OS's diferentes as coisas nem sempre funcionam como esperas (um exemplo classico e' a mistura de SIGPIPE's e threads em HP-UX 10.x). Claro que podes usar mascaras de sinais por threads, mas novamente nao e' infelizmente algo em que toda a gente segue o standard POSIX e e' um dos pontos mais dificeis de acertar em multi-plataformas (e' por isso que usar 'native-threads' em Java e' desaconselhado). "It encourages monolithic programs": perdão? Eu pensava que o objectivo de usar threads era *separar* partes independentes do programa... A definicao de monolitico neste caso refere-se a teres tudo a correr num so' processo -- em vez de teres processos que usem IPC de alto nivel que distribuem o trabalho (potencialmente por maquinas diferentes). Tudo depende do problema, mas, por exemplo, o que te parece mais simples: um servidor que arranca uma nova thread para resolver um pedido e esquece-a; um servidor que usa poll(2) ou select(2) e ou é monolítico ou guarda callbacks; ou um servidor que usa AIO? E é preciso notar que o segundo está sujeito a bloqueios no IO de que é necessário se precaver. AIO e processamento asincrono utilizando poll(2) e select(2) (embora o select seja muito mais ineficiente) e' para muitos casos (quando tens que processar em "bursts" como num servidor HTTP) a melhor opcao -- e' por isso que o Zeus usa um modelo asincrono com Non-Blocking I/O, e qualquer base de dados que se preze usa AIO para escrever/ler de discos. Threads adaptam-se melhor quando o tempo de processamento e' longo (e.g., calculo numerico) e quando nao tens que manter estado entre estadios do processamento. E' neste sentido que eu acho que "Threads are Evil" -- mas como disseste (e bem) por vezes nao tens outra opcao -- mas nao tenhas duvida que se puderes, *deves* evita-las. Se estiveres interessado, posso mandar-te um "mini-proxy HTTP" que escrevi (C++) como demonstracao de como escrever codigo tipo NB I/O usando um modelo de poll(2) com callbacks. Para a maioria dos casos, e' cerca de 65% mais eficiente que um modelo "threaded" para processamento semelhante. Regards, echo '[dO%O+38%O+PO/d00]Fi22os0CC4BA64E418CE7l0xAP'|dc
|
| | | | "um agente que distribui o trabalho por varios sub-agentes que ainda dependem do agente principal" Cada thread é independente da outra e pode por si criar e destruir outras threads. O modelo de um agente a distribuir o trabalho pelos sub-agentes é mais aplicável no caso de programas que têm uma única função. "um exemplo ilustrativo de porque "multi-threading" nao e' realmente ideal e' o facto de teres concorrencia *mas* uma heap partilhada." Essa é, quanto a mim, a *vantagem* de threads. Fazer um 10xfork() e usar shared memory e semáforos (postgresql) é indecente. Para isso se inventaram threads, além de que não se tem o overhead da syscalls para o caso dos semáforos. A própria existência the IPC, e em particular de shared memory, indica a necessidade da existência de threads, e de que, para certos casos, são o melhor modelo a usar. "ja' experimentaste misturar sinais UNIX com threads?" Não, a única coisa que faço com o SIGPIPE é bloqueá-lo, e verificar os erros de write(2) e sendto(2). De resto, usar sinais c/ threads como forma de IPC não faz muito sentido, e as cond têm funcionado nos meus casos particulares. (BTW FAQ-threads). "AIO e processamento asincrono utilizando poll(2) e select(2) (embora o select seja muito mais ineficiente) e' para muitos casos (quando tens que processar em "bursts" como num servidor HTTP) a melhor opcao -- e' por isso que o Zeus usa um modelo asincrono com Non-Blocking I/O, e qualquer base de dados que se preze usa AIO para escrever/ler de discos. Threads adaptam-se melhor quando o tempo de processamento e' longo (e.g., calculo numerico) e quando nao tens que manter estado entre estadios do processamento." AIO *é* a forma de obter a melhor performance quando se trata de muito I/O. E como espero um http server e rdbms server use AIO para I/O, também espero que usem threads para distribuir o cálculo necessário em muitos casos. (e quais, actualmente, não usam?) "E' neste sentido que eu acho que "Threads are Evil" -- mas como disseste (e bem) por vezes nao tens outra opcao -- mas nao tenhas duvida que se puderes, *deves* evita-las." Não acho que threads sejam Evil, mas também não acho que se devam usar em tudo (bash c/ 30 threads, ls c/ umas 4, etc, seria muito engraçado :)). Mas chateia-me que algumas pessoas sejam inconscientes e que não liguem ao paralelismo subjacente ao próprio programa e não o aproveitem. Nem teria que ser forçosamente usando threads, bastava ir correndo os outros processos que são independentes... "Se estiveres interessado, posso mandar-te um "mini-proxy HTTP" que escrevi (C++) como demonstracao de como escrever codigo tipo NB I/O usando um modelo de poll(2) com callbacks. Para a maioria dos casos, e' cerca de 65% mais eficiente que um modelo "threaded" para processamento semelhante. " Thanks, mas estaria mais interessado no benchmark que usaste. :) Eu já fiz um http-proxy, em C, que usava select, mas nao NB, e actualmente econtro-me a fazer um servidor de IM genérico, e precisei das callbacks para as implementações independentes dos serviços.
hugs Strange |
| | | | Thanks, mas estaria mais interessado no benchmark que usaste. :) http-load com 64 clientes, 2000 pedidos HTTP/1.1 por cliente. Regards, echo '[dO%O+38%O+PO/d00]Fi22os0CC4BA64E418CE7l0xAP'|dc
|
| | | | E em ambos os casos usaste os mesmos hosts? E a tua proxy fazia cache dos pedidos? (O que fiz foi apenas um port-forwarding c/ logging: plug.c plugv2.c.) Experimentaste misturar threads c/ AIO? Posso ir buscar a source do teu prog? (Espero não te estar a chatear com tantas perguntas...)
hugs Strange |
| | | | E em ambos os casos usaste os mesmos hosts? E a tua proxy fazia cache dos pedidos? (O que fiz foi apenas um port-forwarding c/ logging: plug.c plugv2.c.) Experimentaste misturar threads c/ AIO? Posso ir buscar a source do teu prog? Sem cacheing, NB I/O com poll(2) -- nao usei threads -- comparei com o squid com o cacheing desligado. Nao podes puxar a fonte, mas tenho todo o gosto em ta mandar se me deres um e-mail (nota, o "proxy" nao e' um proxy HTTP -- faz apenas port forwarding como o teu). Regards, echo '[dO%O+38%O+PO/d00]Fi22os0CC4BA64E418CE7l0xAP'|dc
|
| | | | | ha dois anos foi o ano do Dragão, o ano passado foi o ano do Windoze CodeRed e variantes Este parece que vai ser o ano do Solaris! :D
.:}50 anos sobre a Terra e sobre o Mar{:. |
| | | | | buracos ??? Não deves ter lido o artigo.
Pedro Esteves |
| | | | passei de gozao :D a despropositado ;( mas prontos ;) 2002-04-30: Sun Solaris RWall Daemon Syslog Format String Vulnerability 2002-04-29: Solaris admintool Local Buffer Overflow Vulnerability 2002-04-29: CDE DTPrintInfo Help Volume Search Buffer Overflow Vulnerability 2002-04-29: Solaris cachefsd Buffer Overrun Vulnerability 2002-04-29: Solaris AdminTool Media Installation Path Buffer Overflow Vulnerability 2002-04-29: Solaris LBXProxy Display Name Buffer Overflow Vulnerability 2002-04-29: Solaris cachefsd Denial of Service Vulnerability 2002-04-22: BSD exec C Library Standard I/O File Descr1ptor Closure Vulnerability
.:}50 anos sobre a Terra e sobre o Mar{:. |
| |
|