Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

Parallel Programming in C

Options
  • 22-02-2005 3:46pm
    #1
    Closed Accounts Posts: 13


    Hello all

    I want to learn how to run two processes cxoncurrently using C.

    One outputting a value via the NIDAQ card and reading in another value.
    Storing read values in an array.

    The other would be processing the previous contents of the above array.

    Help/Advice of any kind would be much appreciated.

    Thanks.


Comments

  • Registered Users Posts: 2,426 ✭✭✭ressem


    win or lin?

    Posix multithreading is easy enough at the basic level.

    http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html

    or
    http://www.linuxjournal.com/article/1363
    http://www.cs.cf.ac.uk/Dave/C/node29.html#SECTION002940000000000000000

    Then make sure that the call you use are thread safe.
    Beyond that it's standard CS stuff, making sure that you're not processing deleted or unfinished entries using pthread_mutex_lock and unlock.


  • Registered Users Posts: 2,002 ✭✭✭bringitdown


    FYI: Parallel Programming is a slightly different paradigm than multi-process or multi-threaded programing on the same machine.

    Parallel as I would understand refers to a PVM or MPI type implementation - the same code executing on multiple machines on the same problem with a different data set for example.

    e.g: http://www.cs.usfca.edu/mpi/


  • Closed Accounts Posts: 13 01friel


    Thanks guys

    I'm working on windows.


  • Registered Users Posts: 2,426 ✭✭✭ressem


    On win32 you've got

    The _beginthread function
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt__beginthread.2c_._beginthreadex.asp

    btw
    http://www.flounder.com/badprogram.htm#beginthread
    "
    The functions will generate a compiler error if you have not gone into Project | Settings | Code Generation and selected the multithreaded library
    "

    or a Posix library for windows, but that may be over the top for your prog.


  • Closed Accounts Posts: 13 01friel


    This looks good, Will try this out,

    Thanks


  • Advertisement
  • Closed Accounts Posts: 13 01friel


    Hello Again!

    Still Having difficulties!

    Resuming Thread in for loop then waiting for it to finish and then resume it again with a new section of array.

    Do I need Handles?

    Thanks,


  • Registered Users Posts: 2,426 ✭✭✭ressem


    Can you provide the code or pseudo code?

    What are you using to resume and suspend the thread?
    Using Mutex , events , critical section?

    http://www.codeproject.com/threads/sync.asp


  • Closed Accounts Posts: 13 01friel


    Thanks for the links dude, very useful.

    I think I'm gettin there.


  • Closed Accounts Posts: 13 01friel


    Hi Guys,

    Is there any way of making sure that the mutex will go to a different thread each time it is released?

    It seems to be staying in one thread all the time although it does swap after a while?

    Thanks


  • Registered Users Posts: 2,002 ✭✭✭bringitdown


    How have you implmented the lock?

    Do you do the following in pseudo code....

    Thread 1: Lock(m)
    Thread 2: Lock(m)
    Thread 1: got lock process critical section
    Thread 2: Blocked - Waiting for lock
    Thread 1: Unlock(m)
    Thread 2: got lock process critical section
    Thread 1: Lock(m)
    Thread 2: Unlock(m)
    Thread 1: got lock process critical section
    Thread 2: Lock(m)
    Thread 2: Blocked - Waiting for lock

    ... and so on, assuming you are using pthreads and defaults.

    Basically the call to pthread_lock_mutex will block the caller and place it on a FIFO queue. First to request the lock will be the next to get it.


  • Advertisement
  • Registered Users Posts: 2,426 ✭✭✭ressem


    With trouble I guess...

    Ideally you'd use a thread queue but,

    What is your thread doing? The Card IO or the processing? Both? Are multiple threads co-ordinating to carry out the processing?

    The purpose of threads is to allow the program to keep working while you're waiting for IO or to split tasks across multiple processors.

    It sounds as though the thread is just grabbing and dropping the mutex, suggesting that it's spending no time doing IO or the IO is being done while the mutex is still blocking other threads from starting.

    So can you provide Pseudo code + comment on where thread is spending most time e.g. file io/ card io/ console io.


  • Closed Accounts Posts: 7,563 ✭✭✭leeroybrown


    What you're trying to do sounds quite like the Producer-Consumer design pattern.

    What advantage do you hope to gain from having a multi-threaded application to deal with the Nidaq data?


  • Closed Accounts Posts: 13 01friel


    HANDLE hMutex;

    \\In main
    hMutex = CreateMutex(0, FALSE, 0);

    \\At the end of a for loop in main(i from 0 to 16)
    if(i == 0)
    {
    _beginthread(Thread, 0, NULL); // Start the Thread
    }
    else
    {
    WaitForSingleObject(hMutex, INFINITE);
    ReleaseMutex(hMutex);
    }`

    _endthread();//After for loop

    \\In thread
    hMutex = CreateMutex(0, FALSE, 0);
    WaitForSingleObject(hMutex,INFINITE);
    \\In for loop (i from 0 to 16 also)
    WaitForSingleObject(hMutex,INFINITE);//At start
    ReleaseMutex(hMutex);//At end

    The for loop in main runs 15 times most of the time(also 10,12,4)
    Then the program goes to Thread and it is executed in it's entirity before it returns to main;

    This is a final year project I hope to gain marks and experience by getting this working

    Sorry about the delay
    and THANKS for all the help!


  • Registered Users Posts: 2,002 ✭✭✭bringitdown


    I'm not overly familiar with the Windows / MFC threading library but you have two calls to CreateMutex, also I think you're logic is a bit off...

    According to MS docs if lpName is NULL, the mutex object is created without a name -
    So if you have a mutex in main created this way and you call CreateMutex again in the thread you'll have 2 mutexes - one used in the thread, one used in main.

    Win32 people correct if I'm wrong.

    In main create your named mutex:
    HANDLE mx_mutex; // prob. needs GLOBAL scope
    
    // Create a mutex with initial owner.
    mx_mutex = CreateMutex( NULL, TRUE, "CsMutex");
      ReleaseMutex(mx_mutex));
    
    // Create threads
    
    // Wait for thread termination
    
    

    In the thread, request the same named mutex
    mx_mutex = CreateMutex( NULL, TRUE, "CsMutex");
    
    // Wait for ownership
    res = WaitForSingleObject( mx_mutex, 5000L);
    
    // Check takes ownership
    
    // Do critical section processing
    
    // Release Mutex
    ReleaseMutex(mx_mutex))
    
    [/code]

    i.e.
    create a mutex accessible to all threads (main is going to execute in a thread!)

    request access before critical section to that mutex
    do critical section
    release mutex


  • Closed Accounts Posts: 13 01friel


    Thanks Bring it down

    This is working but the mutex aint going to a different thread each time,
    I want thread 1 to go first and then thread 2 and then thread 1 again but the mutex seems to stay in one thread a lot but it does change?


  • Registered Users Posts: 2,426 ✭✭✭ressem


    Not really surprising.

    You have a

    waitingforsingleobject
    releasemutex

    in a tight loop in the thread, so unless some other system process stalls your thread, or you call releasemutex just immediately before the other thread does it's signal check, the thread will grab it back immediately each time.

    It takes time before a mutex is released and the signal is received, about 15 milliseconds till the next time slice.

    If you pretended to be doing real work by calling Sleep(0) after releasing the mutex within the thread, you should see the other thread getting the mutex, and vice versa. Bit pointless though. Might as well be writing single threaded code if you've that in your exercise.

    Also, i agree, lose the threads createmutex and you should have another releasemutex, following WaitforSingleObject

    Also the _endthread probably isn't wanted, the thread calls it itself, when it finishes, using this in real code might result in improper cleanups.
    If you want to make sure that it's finished you can use _beginthreadex
    extract from
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/vclrfAThroughF.asp

    HANDLE hThread;
    unsigned threadID;
    hThread = (HANDLE)_beginthreadex( NULL, 0, &SecondThreadFunc, NULL, 0, &threadID );

    WaitForSingleObject( hThread, INFINITE );
    CloseHandle( hThread );


  • Closed Accounts Posts: 13 01friel


    Thanks Ressem

    But when I take _endthread out, Thread dosen't get executed at all!
    Are there any viable alternatives to mutexes?


  • Registered Users Posts: 2,426 ✭✭✭ressem


    About alternatives, sure lots of them, but most act in a similar manner. E.g those mentioned in the codeproject link:

    However no offense meant, but you still haven't mentioned why you're using mutexes at all.
    Are you protecting writes to the array between the wait and release?

    You appear to be using it to turn multithreading into task switching as far as I've seen, which is ... odd.

    If you use the _beginthreadex code below, and remove all mutexes, and both loop lengths are greatly increased, you should see both threads contending for time slices.
    Otherwise, one task then the other will get done in one time slice.

    endthread is just stopping your main routine AFAIK, so what happens if you do replace it with
    WaitForSingleObject( hThread, INFINITE );
    ?

    .


Advertisement