multithreading - Why do I get Access Violation in mutithreading aplication in C while I exit the main() before the threads finish? -


i have 1 program, create 4 threads wait 1st thread[0]. threads print contents. when below program access violation sometimes.

#include<windows.h> #include <stdio.h> #include<tchar.h>  #define keylen 8 #define datalen 56 typedef struct _record{     char key[keylen];     tchar data[datalen];         }record; #define recsize sizeof(record) typedef record *lprecord;  typedef struct _threadarg{     dword ith;     lprecord lowrecord;         // pointer low record      lprecord highrecord; } threadarg, *pthreadarg;  static int keycompare(lpctstr, lpctstr); static dword winapi sortthread(pthreadarg ptharg); static dword nrec;  // total number of records sorted static handle *pthreadhandle;   dword options (int argc, lpctstr argv [], lpctstr optstr, ...);  int _tmain(int argc, lptstr argv[]){ handle hfile, mhandle; lprecord precords = null; dword lowrecordnum, nrecth,numfiles, ith; large_integer filesize; bool noprint; int iff, inp; pthreadarg threadarg; lptstr stringend;  inp = 1; iff = inp + 1; numfiles = _ttoi(argv[inp]);  if (argc <= iff)     _tprintf (_t ("usage: sortmt [options] nth files."));  /* open file , map */ hfile = createfile (argv[iff], generic_read | generic_write, 0, null, open_existing, 0, null); if (hfile == invalid_handle_value)     _tprintf (_t ("failure open input file."));  if (!setfilepointer(hfile, 2, 0, file_end) || !setendoffile(hfile))     _tprintf (_t ("failure position extend input file."));  mhandle = createfilemapping(hfile, null, page_readwrite, 0, 0, null); if (null == mhandle)     _tprintf (_t ("failure create mapping handle on input file."));  /* file size. */ if (!getfilesizeex (hfile, &filesize))     _tprintf (_t ("error getting file size."));  nrec = (dword)filesize.quadpart / recsize;   nrecth = nrec / numfiles;    threadarg = malloc (numfiles * sizeof (threadarg)); /* array of thread args. */  pthreadhandle = malloc (numfiles * sizeof (handle));  /* map entire file */ precords = mapviewoffile(mhandle, file_map_all_access, 0, 0, 0);  if (null == precords)     _tprintf (_t ("failure map input file.")); closehandle (mhandle);  /* create sorting threads. */ lowrecordnum = 0; (ith = 0; ith < numfiles; ith++) {     threadarg[ith].ith = ith;     threadarg[ith].lowrecord = precords + lowrecordnum;     threadarg[ith].highrecord = precords + (lowrecordnum + nrecth);     lowrecordnum += nrecth;     pthreadhandle[ith] = (handle)_beginthreadex (         null, 0, sortthread, &threadarg[ith], create_suspended, null); }  /* resume suspened threads. */  (ith = 0; ith < numfiles; ith++)     resumethread (pthreadhandle[ith]);   /* wait sort-merge threads complete. */  waitforsingleobject (pthreadhandle[0], infinite);    (ith = 0; ith < numfiles; ith++);     closehandle (pthreadhandle[ith]);  //sleep(3);  // un comment , see no error.   unmapviewoffile(precords); // restore file length /* setfilepointer convenient it's short addition file end */ if (!setfilepointer(hfile, -2, 0, file_end) || !setendoffile(hfile))     _tprintf("failure restore input file lenght.");  closehandle(hfile); free (threadarg); free (pthreadhandle); return 0; }   dword winapi sortthread(pthreadarg ptharg){  dword groupsize = 2, mynumber, twotoi = 1;         /* twotoi = 2^i, merge step number. */ dword_ptr numbersingroup; lprecord first;  mynumber = ptharg->ith; first = ptharg->lowrecord;  numbersingroup = (dword)(ptharg->highrecord - first);   printf(" %d : %s \n",mynumber,  ptharg->lowrecord );  return 0; } 

file content structure:

02d2d159. record number: 00000000.abcdefghijklmnopqrstuvwxyz x f362711e. record number: 00000001.abcdefghijklmnopqrstuvwxyz x ba957dff. record number: 00000002.abcdefghijklmnopqrstuvwxyz x 

but if give sleep(n); after threads creation there no problem.! understood main() thread exits before child threads. when main() exits entire process should terminate. isn't it? how access violation possible?

why access violation?

but when main() exits entire process should terminate.

ultimately yes, between return main , actual process termination may lot of code running, tearing down process image etc.

thus, when ...

free (threadarg); free (pthreadhandle); 

... , 1 or more threads haven't yet completed , ...

printf(" %d : %s \n",mynumber,  ptharg->lowrecord ); 

... access example thread argument ptharg (which deleted) you've signed trouble.

note example. there's more (internal) shared data freed after return main still used threads (their stacks example, thread handles, ...).

moral: wait all threads use resource terminate before freeing resource.


also: ptharg->lowrecord not char * expected %s, have undefined behavior there, too.


Comments

Popular posts from this blog

javascript - Thinglink image not visible until browser resize -

firebird - Error "invalid transaction handle (expecting explicit transaction start)" executing script from Delphi -

mongodb - How to keep track of users making Stripe Payments -