Multithreading - Programm absturz



  • Linkst du auch gegen die Multithreaded Runtime-Library?



  • Multitaks schrieb:

    Erhalte mit "_beginthreadex" folgende Fehlermeldung:

    Microsoft (R) Incremental Linker Version 6.00.8168
    Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
    test.obj : error LNK2001: unresolved external symbol __beginthreadex
    Debug/Test.exe : fatal error LNK1120: 1 unresolved externals
    Error executing link.exe.
    

    Hier ein auszug aus process.h

    /* function prototypes */
    #ifdef  _MT
    _CRTIMP unsigned long  __cdecl _beginthread (void (__cdecl *) (void *),
            unsigned, void *);
    _CRTIMP void __cdecl _endthread(void);
    _CRTIMP unsigned long __cdecl _beginthreadex(void *, unsigned,
            unsigned (__stdcall *) (void *), void *, unsigned, unsigned *);
    _CRTIMP void __cdecl _endthreadex(unsigned);
    #endif
    

    Es ist ersichtlich, dass der Compiler _beginthreadex nur dann erkennt wenn _MT definiert ist, also guggst mal oben was ich da geschrieben habe!



  • Du scheinst ja noch VS6 zu nutzten, also so gehts:
    Projekt settings



  • Ok danke für die Antwort hat geholfen.
    Jetzt neuer Fehler:

    D:\Privat\Test.c(83) : warning C4047: 'function' : 'unsigned int (__stdcall *)(void *)' differs in levels of indirection from 'int '
    D:\Privat\Test.c(83) : warning C4024: '_beginthreadex' : different types for formal and actual parameter 3
    D:\Privat\Test.c(83) : warning C4047: '=' : 'void *' differs in levels of indirection from 'unsigned long '
    

    Hier der Aufruf:

    thread = _beginthreadex (NULL,0,irc_start(),NULL,0,&id);
    


  • Multitaks schrieb:

    thread = _beginthreadex (NULL,0,irc_start(),NULL,0,&id);
    
    thread = _beginthreadex (NULL,0,(void *)irc_start, NULL,0,&id);
    

    keine Klammern bei irc_start, dafür aber mit (void 😉 casten.



  • Noch die Erklärung: Wenn du die Klammern hinter deinen Funktionsnamen stellst, dann ist das ein Funktionsaufruf (es würde also die Rückgabe der Funktion an _beginthreadex übergeben). Du willst aber einen Zeiger auf die Funktion übergeben, dass stellt der Name ohne Klammern dar. Und da _beginthreadex einen void-Pointer haben will, castest du entsprechend, und alles ist in Butter! 😉



  • Wieder Fehlermeldung:

    warning C4047: '=' : 'void *' differs in levels of indirection from 'unsigned long '
    

    -.-



  • Multitaks schrieb:

    cpp]
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>

    void thread();

    int main(int argc, char *argv[])
    {
    HANDLE thread;
    DWORD id;
    int i,index;
    i++;
    thread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)thread,(LPVOID)i,0,&id);

    system("PAUSE");
    return 0;
    }

    void thread() {
    int index;
    for (index=0; index<100; index++)
    {
    printf("%d",index);
    Sleep(1000);
    }

    }
    [/cpp]

    Mann du bist ein Spezi, du bennenst HANDLE thread; und dann gibt es da auch noch die Funktion thread. Is wohl klar das dann mal nicht geht. Lerne erstmal den Funktionen Namen zu geben die auch irgendwie der Funktionsweise der Funktion entsprechen. Man nennt auch keine Funktion öffne_Wasserhahn(..) wenn man damit das Licht anschalten will.



  • Multitaks schrieb:

    Wieder Fehlermeldung:

    warning C4047: '=' : 'void *' differs in levels of indirection from 'unsigned long '
    

    -.-

    Des ist eigentlich des aktuelle Problem.



  • Ok komme jetzt eigentlich mit der Funktion ganz gut klar.

    Wenn du die Klammern hinter deinen Funktionsnamen stellst, dann ist das ein Funktionsaufruf (es würde also die Rückgabe der Funktion an _beginthreadex übergeben). Du willst aber einen Zeiger auf die Funktion übergeben, dass stellt der Name ohne Klammern dar.

    Stimmt nicht.
    Lasse ich die Klammern hintern dem Funktionsnamen weg dann wird die Funktion nicht aufgerufen.
    Schreibe ich die Klammern hintern den Funktionsnamen dann läuft alles glatt.



  • Dann zeig mal deinen Aufruf.



  • thread = _beginthreadex (NULL,0,(void *)irc_start, NULL,0,&id);
    

    Da passiert irgendwie nix.
    Mache ich es aber so:

    thread = _beginthreadex (NULL,0,(void *)irc_start(), NULL,0,&id);
    

    Klappt es komischer weiße



  • Klappt es komischer weiße

    Fragt sich bloss was es ist. Wenn Du damit den Funktionsaufruf von irc_start() meinst, stimmt. Es klappt. Jedoch nicht auf einem neuen Thread.
    (Lässt sich leicht mit GetCurrentThreadId() überprüfen.

    Werde Dir ein Mini Bsp. schreiben.. ich kann das nicht mehr mitansehen...
    Simon

    Edit:
    Hier das Bsp:

    #include "stdafx.h"
    #include <tchar.h>
    #include <process.h>
    #include <windows.h>
    #include <string>
    #include <sstream>
    
    ///////////////////////////////////////////////////////////////////////////////
    
    void printCurrentThreadId(const std::wstring& msg)
    {
    	std::wostringstream oss;
    	oss << msg << L", Thread Id = " << GetCurrentThreadId() << std::endl;
    	OutputDebugStringW(oss.str().c_str());
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    
    unsigned int __stdcall threadProc(void* /*arg*/)
    {
    	printCurrentThreadId(L"threadProc(..)");
    	return 0;
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    
    int _tmain(int /*argc*/, _TCHAR* /*argv*/[])
    {
    	printCurrentThreadId(L"_tmain(..)");
    
    	unsigned int threadId = 0;
    	HANDLE threadHandle = reinterpret_cast<HANDLE>(_beginthreadex(0, 0, &threadProc, 0, 0, &threadId));
    
    	// Warte bis der neue Thread beendet wurde.
    	WaitForSingleObject(threadHandle, INFINITE);
    	CloseHandle(threadHandle);
    }
    
    ///////////////////////////////////////////////////////////////////////////////
    

Anmelden zum Antworten