Friday, March 6, 2009

Interview questions

1) What's the difference between fopen and open?
fopen/fread/fwrite have buffer to fasten I/O process, but open/read/write
dosen't

open() is not standard and might not be implemented in some standard-conforming hosted environments, whereas fopen() is standard and is implemented in all standard-conforming hosted environments. Therefore for portability, use the standard functions, not (emulated)
Unix system service calls.

There are other functional differences, the most notable being that the stdio stream uses a buffer in "user space", whereas the direct system-call I/O does not. (There might or might not be kernel-space buffers in both cases.) This can matter if record length is important; for example, if you want to write a magnetic tape record of length 80, write(fd,buf,80) will do that, whereas fwrite(buf,80,1,fp) will likely just put the data in a user-space buffer, with the actual write occurring eventually when the buffer is full - which will result in something like a 512-byte
magtape record. You could perhaps work around that by issuing a fflush(fp) after the fwrite(), but it's a kludgy way to accomplish what write() does directly.

2) Difference between Threads and process

A single process can have multiple threads that share global data and address space with other threads running in the same process, and therefore can operate on the same data set easily. Processes do not share address space and a different mechanism must be used if they are to share data.
If we consider running a word processing program to be a process, then the auto-save and spell check features that occur in the background are different threads of that process which are all operating on the same data set (your document).

Creation of new process requires new resources and Address space whereas the thread can be created in the same address space of the process which not only saves space and resources but are also easy to create and delete,and many threads can exhists in a process.

Threads share the address space of the process that created it; processes have their own address.

Threads have direct access to the data segment of its process; processes have their own copy of the data segment of the parent process.


Threads can directly communicate with other threads of its process; processes must use inter-process communication to communicate with sibling processes.

Threads have almost no overhead; processes have considerable overhead.

New threads are easily created; new processes require duplication of the parent process.

Threads can exercise considerable control over threads of the same process; processes can only exercise control over child processes.

Changes to the main thread (cancellation, priority change, etc.) may affect the behavior of the other threads of the process, changes to the parent process does not affect child processes.


Both have an id, set of registers, state, priority, and scheduling policy.

Both have attributes that describe the entity to the OS.

Both have an information block.

Both share resources with the parent process.

Both function as independent entities from the parent process.

The creator can exercise some control over the thread or process.

Both can change their attributes.

Both can create new resources.

Neither can access the resources of another process.


3) Difference between mutex and critical section

A concrete example of program using a mutex between process, is the registry (advapi32.dll).

All registry operations use the same mutex to modify the internal hash-table that represents the registry (Under Windows 95 and 98 at least).

So remember (on multiprocessor platform at least) that a registry function is relatively slow.

I think that CriticalSections use internally a Semaphore, and that a request to a critical section is very, very fast if the critical section if not currently used (for many applications, that is almost always the case), and if not it is slow like a normal mutex or semaphore.

Quite often you'll see reference to the speed differences between the user mode critical section and the kernel objects mutex and semaphore. I really don't pay much attention to these 'speed' differences because either you can use a critical section or you can't.

If you are synchronizing data shared between multiple threads of the same process, you can use a critical section. Yes, you *could* use a mutex or semaphore, but they will be a few clock cycles slower because they are kernel objects. A good general usage rule is: When in the same process, prefer to use the critical section.

When you are synchronizing data shared between multiple processes, you can't use a critical section. So it doesn't matter that the mutex or semaphore is slower than the critical section, since you can't use a critical section anyway across processes.

I usually follow this rule: "Slower, properly synchronized data is still better than fast, corrupt data!"

A critical section object provides synchronization similar to that provided by a mutex object, except that a critical section can be used only by the threads of a single process. Event, mutex, and semaphore objects can also be used in a single-process application, but critical section objects provide a slightly faster, more efficient mechanism for mutual-exclusion synchronization (a processor-specific test and set instruction). Like a mutex object, a critical section object can be owned by only one thread at a time, which makes it useful for protecting a shared resource from simultaneous access. Unlike a mutex object, there is no way to tell whether a critical section has been abandoned.

No comments: