You are on page 1of 5

7/21/2017

Basic Terms
• Multiprocessor, Uni-processor
• Asynchronous
– Two entities can proceed independently.
– Non blocking behavior
Multithreading in UNIX • Synchronous
– Two entities cannot proceed independently.
– Blocking behavior
• Parallelism
Harshad B. Prajapati – Concurrent sequences that proceed simultaneously.
– True parallelism can occur only on multiprocessor system, but concurrency can
Associate Professor occur on both uni-processor and multiprocessor systems
Information Technology Department, • Concurrency
– Things happening at the same time.
Dharmsinh Desai University, Nadiad – Appears to happen at the same time, could occur serially . (Illusion of
parallelism)
– Concurrent operations (of threads) may be interleaved.

Concurrency Control Multi-tasking in UNIX


• Three basic functions
• Management of Execution Context – Create a new process using fork
– E.g. Thread Control Block (store and load) – Wait for another process
– Load a new program in a current process using exec variants.
• Scheduling • System call:
– pid_t fork(void);
– Taking decision which entity should execute at – Use header files
given point of time • #include <sys/types.h>
• #include <unistd.h>
• Synchronization • Important: It is called once but it returns twice (in parent and child
processes).
– For coordinated use of shared resources • fork() creates a child process that differs from the parent process only
in its PID and PPID. The child process is an exact duplicate of parent
process
• All descriptors open in the parent before call to fork are shared with
the child after fork returns.
• File locks and pending signals are not inherited.

Multi-tasking in UNIX Multi-tasking in UNIX


• On success,
wait for a child process to stop or terminate
– Parent process gets the PID of the child process
– Child process gets return value 0. • suspend execution of the calling process
(Important: The parent and child processes are – until status information for one of the terminated
identified based on these return values in the code)
child processes of the calling process is available,
• On failure, a -1 will be returned in the parent's context, no – or until delivery of a signal whose action is either
child process will be created, and errno will be set to execute a signal-catching function or to
appropriately.
– EAGAIN: scarcity of necessary resources or the system- terminate the process.
imposed limit on the total number of processes
– ENOMEM: Insufficient storage space is available.

1
7/21/2017

Multi-tasking in UNIX Multi-tasking in UNIX


• System Calls • pid_t wait(int *status);
– pid_t wait(int *status); – Return value pid_t indicates which child returned
– pid_t waitpid(pid_t pid, int *status, int options); to calling process (generally used if there are
– Use header files: #include <sys/types.h> and multiple child processes running)
#include <sys/wait.h> – The status is value result argument
• It gives status of the terminated child process. If we are
• The waitpid() function is equivalent to wait() if not interested, pass NULL.
the pid argument is -1 and the options
argument is 0.

Multi-tasking in UNIX Multi-tasking in UNIX


• pid_t waitpid(pid_t pid, int *status, int options);
• pid_t waitpid(pid_t pid, int *status, int options);
• If pid = -1, • The options argument is constructed from the bitwise-
– status is requested for any child process. waitpid() is equivalent to inclusive OR of zero or more of the flags. There are
wait().
• If pid > 0, many more, only important are listed.
– Status is requested for particular child process (whose process id is – WNOHANG: return immediately if no child has exited.
pid)
• If pid=0, • Using status argument, we can know status of a
– status is requested for any child process whose process group ID is returned process using macros
equal to that of the calling process.
• If pid<-1, – E.g. WIFEXITED(status value): returns true if the child
– status is requested for any child process whose process group ID is terminated normally
equal to the absolute value of pid.

Multi-tasking in UNIX Multi-tasking in UNIX


The wait() function shall fail if: Load new program in the existing process
• ECHILD: The calling process has no existing unwaited-for child
processes. • Exec is a system call used to load a new program
• EINTR: The function was interrupted by a signal. The value of the in the existing process. The process id does not
location pointed to by stat_loc is undefined.
change. However, new program (code, data,
The waitpid() function shall fail if: stack, .. ) is loaded overwriting the current
• ECHILD: The process specified by pid does not exist or is not a child content.
of the calling process, or the process group specified by pid does
not exist or does not have any member process that is a child of the • No return from a successful exec, because the
calling process.
• EINTR: The function was interrupted by a signal. The value of the
calling process image is overlaid by the new
location pointed to by stat_loc is undefined. process image. I.e., It returns to caller only if an
• EINVAL: The options argument is not valid. error occurs while loading the specified program.

2
7/21/2017

Multi-tasking in UNIX Multi-tasking in UNIX


int execl(const char *path, const char *arg0, ... /*, (char *)0 */);
There are six variants of exec system call. See man int execv(const char *path, char *const argv[]);
pages for details. int execle(const char *path, const char *arg0, ... /*,
(char *)0, char *const envp[]*/);
int execve(const char *path, char *const argv[], char *const envp[]);
int execlp(const char *file, const char *arg0, ... /*, (char *)0 */);
int execvp(const char *file, char *const argv[]);

Select when you want Select when you want to load


to load program from Select when you want
program from non-current
current working to specify environment
working directory
directory variables.

Multi-tasking in UNIX POSIX thread


Short Example.
pid_t pid; • Thread API (standard approved by IEEE in
pid =fork();
if(pid<0){
//error
1995)
fprintf(stderr, “Fork Failed\n");
} • Pthread
else if(pid==0){
//Child
// we assign some task to child
execlp("/bin/ls","ls",NULL);
//exit(0); // no meaning of it
}
else{
//parent
//parent waits until child finishes assigned task.
wait(NULL);
exit(0);
}

Thread Life-cycle of a thread


• Light Weight Process • States
– For process: Process Control Block (PCB) – Ready
• PCB is heavy in terms of information it contains
• Takes more time in creation, loading and storing – Running
– For Thread: Thread Control Block (TCB) – Blocked
• Shared code, data, and files – Terminated
• Separate registers and stack

• Extra Points: User Level Thread, Kernel Level


Thread

3
7/21/2017

Pthread Programming Prototype of thread functions


• API headers are in pthread.h file int pthread_create(pthread_t *tid, const pthread_attr_t *attr, void
*(*start_routine)(void*), void *arg);
– Use #include <pthread.h> in your code • If successful, the pthread_create() function returns zero. Otherwise, an
error number (+ve value) is returned to indicate the error.
• Implementation in thread library (.so file) • tid:
– Note: so stands for shared object. similar to windows’ – Upon successful completion, pthread_create() stores the ID of the created thread
dll. in the location referenced by tid
– It Can be used in other functions. E.g. in pthread_join.
• Functions • attr: thread attributes (e.g.priority). If NULL, uses default attributes
– We need functions for • start_routine:
– It is a thread function. The code of this function gets executed as part of the thread
• Creating a thread instance.
• Terminating a thread – Same start_routine can be used for multiple threads (i.e. thread instances)
• Wait for other thread • arg:
– location of data. The data on which the thread will work.
• Data Types (basic) Name Description – It is of generic type to work with different data types.
pthread_t Thread identifier – The code inside thread function should type cast this into appropriate type
pthread_attr_t Thread
attributes object

Prototype of thread functions Prototype of thread functions


• ERRORS void pthread_exit(void *status);
• Function can fail with one of following possible • The pthread_exit() function terminates the
Error codes.
calling thread, making its exit status available
– EAGAIN: scarcity of resources, limit imposed by on the
total number of threads in a process to any waiting threads.
(PTHREAD_THREADS_MAX ). • An implicit call to pthread_exit() occurs when
– EINVAL: The value specified by attr is invalid.
any thread returns from its thread routine.
– EPERM: The caller does not have appropriate
permission to set the required scheduling parameters (With the exception of the initial thread, at
or scheduling policy. which time an implicit call to exit() occurs)

Prototype of thread functions Prototype of thread functions


wait for thread termination
int pthread_join(pthread_t tid, void **value_ptr); To get thread ID of calling thread
• The pthread_join() function suspends execution of the calling thread until the
target thread terminates, except the target thread has already terminated. pthread_t pthread_self(void);
• The value passed to pthread_exit() by the terminating thread is made available in
the location referenced by value_ptr
• When a pthread_join() returns successfully, the target thread has been terminated.

ERRORS Similar to getpid about process


The pthread_join() function will fail if:
• EINVAL: The implementation has detected that the value specified by thread does
not refer to a joinable thread.
• ESRCH: No thread could be found corresponding to that specified by the given
thread ID.
The pthread_join() function may fail if:
• EDEADLK: A deadlock was detected or the value of thread specifies the calling
thread.

4
7/21/2017

Prototype of thread functions Prototype of thread functions


Making a thread detached • int pthread_detach(pthread_t tid);
• A thread is
– Either joinable (the default)
– or detached. • This function can be called by the thread
• For joinable thread, itself.
– thread ID and exit status retained until another thread calls
pthread_join. – pthread_detach(pthread_self());
• (similar to zombie state, and usage of wait or waitpid).
• A detached thread is like
– a daemon process.
• All resources are released when it terminates.

Program Program
// File: threadDemo.c // File: threadDemo.c (continued)
#include <stdio.h>
#include <pthread.h> void* counter(void* param){
void* counter(void*); int* count= (int*)param;
int main(){
pthread_t tid1,tid2; int i=0;
int counter1=5; for(i=0;i<*count;i++)
int counter2=7;
pthread_create(&tid1,NULL,counter,(void*)&counter1); printf("Count=%d\n",i);
pthread_create(&tid2,NULL,counter,(void*)&counter2); pthread_exit(0);
pthread_join(tid1,NULL);
pthread_join(tid2,NULL); }
}

Compilation and Execution


• Execute following command on command prompt • The End
$gcc pthreadDemo.c -o pthreadDemo –lpthread
(Here –l stands for library and pthread is name of library)
Or
gcc pthreadDemo.c /usr/lib/libpthread.so –o
pthreadDemo
(The /usr/lib/libpthread.so is a file that contains
implementation of pthread API. On most systems it is
under /usr/lib)
• Execute following on command prompt
./threadDemo

You might also like