Thread em C, que funcione no DOS puro

Alguém sabe como se implementar uma Thread de C (não C++) para DOS puro?
E que esse código funcione em Windows também (não é obrigatório)?

exemplo simples

feito usando VC++ 6.00 no modo W32 Console

#include <process.h>
#include <stdio.h>

void FunThread(void * param)
{
	for ( int iC=0; iC < 1000000;
				iC++)
				printf( "THREAD - %d\n", iC);

}

void main()
{
	_beginthread(FunThread,
		0, NULL);
//	FunThread(NULL);

	for ( int iC=0; iC < 1000000;
				iC++)
				printf( "MAIN - %d\n", iC);

}

[]'s

Coloque o codigo entre tags <code> </code> para melhor visualização.

DOS ou modo texto?

Se for DOS você tá com problemas pq esse SO não suporta threads.
Se for modo texto, vai em msdn.microsoft.com e procura lá pela documentação toda que voce precisa.

Na verdade, em MS-DOS é possível sim fazer multtask, mas é necessário tomar alguns cuidados.

A técnica utilizada é por timers ou interrupção por I/O de hardware, ou simulando interrupção por software. Usando timers é o que vc mais vai ter controle, fazendo uso das interrupções 23h e 24h.

Em modo texto no Windows, vc pode usar o exemplo que já passei. em MS-DOS, vc pode usar este (detalhe, sou ex-prog em asm, então só tem coisa antiga em asm; este simple tirei de uns livros antigos ke ainda tenho - vc pode compilá-lo usando masm da Microsoft. Se tiver tempo, transcrevo para C):

MUTITHREAD.ASM
; programa exemplo para thread em MS-DOS usando timers
		.xlist
		include 	stdlib.a
		includelib	stdlib.lib
		.list
dseg		segment	para public 'data'
ChildPID	word	0
BackGndCnt	word	0
BkgndPCB	pcb	{0,offset EndStk2, seg EndStk2}
InputLine	byte	128 dup (0)
dseg		ends
cseg		segment	para public 'code'
		assume	cs:cseg, ds:dseg
CritErrMsg	byte	cr,lf
		byte	"DOS Critical Error!",cr,lf
		byte	"A)bort, R)etry, I)gnore, F)ail? $"
MyInt24		proc	far
		push	dx
		push	ds
		push	ax
		push	cs
		pop	ds
Int24Lp:	lea	dx, CritErrMsg
		mov	ah, 9		
		int	21h

		mov	ah, 1		
		int	21h
		and	al, 5Fh		
		cmp	al, 'I'			;Ignore?
		jne	NotIgnore
		pop	ax
		mov	al, 0
		jmp	Quit24
NotIgnore:	cmp	al, 'r'			;Retry?
		jne	NotRetry
		pop	ax
		mov	al, 1
		jmp	Quit24

NotRetry:	cmp	al, 'A'			;Abort?
		jne	NotAbort
		prcsquit			
		pop	ax
		mov	al, 2
		jmp	Quit24

NotAbort:	cmp	al, 'F'
		jne	BadChar
		pop	ax
		mov	al, 3
Quit24:		pop	ds
		pop	dx
		iret

BadChar:	mov	ah, 2
		mov	dl, 7			;Bell character
		jmp	Int24Lp
MyInt24		endp

MyInt23		proc	far
		iret
MyInt23         endp
BackGround	proc
		sti
		mov	ax, dseg
		mov	ds, ax
		inc	BackGndCnt		
		yield				
		jmp	BackGround
BackGround	endp


Main		proc
		mov	ax, dseg
		mov	ds, ax
		mov	es, ax
		meminit
		mov	ax, 0
		mov	es, ax
		mov	word ptr es:[24h*4], offset MyInt24
		mov	es:[24h*4 + 2], cs
		mov	word ptr es:[23h*4], offset MyInt23
		mov	es:[23h*4 + 2], cs

		prcsinit		

		lesi	BkgndPCB	
		fork
		test	ax, ax		
		je	ParentPrcs
		jmp	BackGround	
ParentPrcs:	mov	ChildPID, bx	

		print
		byte	
		byte	cr,lf
		byte	"quickly: ",0

		lesi	InputLine
		gets

		mov	ax, ChildPID	
		kill

		printf
		byte	
		byte	cr,lf,0
		dword	InputLine, BackGndCnt

		prcsquit

Quit:		ExitPgm			
Main		endp

cseg            ends

sseg		segment	para stack 'stack'


stk2		byte	256 dup (?)
EndStk2		word	?

stk		byte	1024 dup (?)
sseg		ends

zzzzzzseg	segment	para public 'zzzzzz'
LastBytes	db	16 dup (?)
zzzzzzseg	ends
		end	Main

tentei colocar dento de mas bagunçado… tentarei de novo depois, caso precise

Faltou desmarcar ‘Desabilitar formatação BB’, done :slight_smile:

[]s

Olá

Já testou isto em algum Windows de verdade (NT, 2000 ou XP)? Ou só funciona em Windows pokemom (95, 98, ME, SE, 3.1, etc.)

[]s
Luca

Olá Luca,

o código asm é para ms-dos/pc-dos (esta da IBM), pois foi pedido pelo hains um código para “DOS Puro”. O primeiro em C é para o shell rodando sob o Windows, oke tira o seu controle e o mantém com a MS.

O código asm funciona também nos pokemons e windows classe NT, a diferença é que no NT/2k/XP precisa acessar I/O requisitando certificado de segurança do kernal do Windows; passado este, o controle fica em suas mãos. Já fiz um trabalho destes 3 anos atrás para uma empresa, ke keria ter acesso direto a porta parela, sem intervenção do w2k (pois os windows são pré-emptivos, oke interrompe a comunicação, sensível em transferências real-time). Funcionou perfeitamente, comprovado em osciloscópio.

Olá

Hemax, não entendi bem o que tem a ver o fato de ser (multitask) preemptivo com o uso da arquitetura em aneis da CPU para o acesso de features que só são acessadas em kernel mode tais como acesso direto aos dispositivos periféricos. Ficou parecendo samba do crioulo doido. Acredito ser uma sorte sua haver pouca gente aqui que conheça bem a arquitetura dos processadores INTEL e AMD e seu aproveitamenmto pelos sistemas operacionais dos micros.

Eu tenho os livros do Jeffrey Richter + NT Server Unleashed + MSCE NT Server Study Guide + Windows NT Technical Support + um bando de livros de ASM e do hardware Intel e alguns milhares de linhas de código escritas em asm e que mesmo assim só conheço 2 meios de acessar a porta paralela com o Windows NT ou superior e nenhum deles trabalha só em user mode.

PS: Nunca ouvi falar de certificado de segurança do kernel

[]s
Luca

olá,

usada erroneamente a palavra, na tentativa de ser simplista demais.

caso consiga autorização, envio o código de acesso a paralela. Este não é fruto de devanios, mas sim um trabalho feito em conjunto com 2 programadores da Microsoft Brasil.

Eu ia falar que vc tem lugar na nasa mas o rigolin vai falar que não.

Então vc tem lugar no Matrix :twisted: