Monday, April 25, 2016

printf, fprintf, sprintf and printk..... whats the difference ?

There are basically 3 standard "streams"

  1. stdin - standard input stream
  2. stdout - standard output stream
  3. stderr - standard error stream
fprintf(standard stream, "message");  //message is sent to the mentioned stream

printf("message"); //message is sent to stdout. so it is as good as writing fprintf(stdout, "message")

#define BUFFER_SIZE 50
char *ch_arr = (char *)malloc(sizeof(char) * BUFFER_SIZE);
sprintf(ch_arr,  "message"); //message is sent to char buffer whose pointer is passed as argument

printk(KERN_IMERG "message");  
//used to print message to kernel log file. Hence it can only be called from kernel only

IPC: Process communication using PIPE

Pipes are basically used for communicating information between two processes.



There are two types of pipes:
  1. ordinary pipe
  2. Named pipe

Ordinary Pipe:

  • simple pipes are unidirectional in nature (one-way comm)
  • two-way communication can be achieved by creating 2 pipes
  • pipe cannot be accessed from the outside the process that creates it
  • Hence it is used mostly for parent and child process communication

creation and use:


  • pipe() function is used to create a pipe. This actually creates special file
  • read(), write(), close() system calls can be used to access this file
  • int file_descriptor[2] array is used as file_descriptor to access file.
    • file_descriptor[0] = read from file
    • file_descriptor[1] = write to file
  • one of the file descriptor(read/write) should be closed in the respective process to make it unidirectional. This is done to avoid Deadlock condition and exploit parallelism

Named Pipes:

  • named pipes are like FIFOs
  • created using mkfifo() system calls and opereated using open, read, write and close(0 system calls
  • they appear as files in file system once created
  • they remain as it is until they are deleted explicitly
  • multiple process on same machine can use named pipe
  • For communication over network, socket wrapper need to be used
Named pipe Example:
$mkfifo demo_fifo
$exec 3<> demo_fifo
$ls -l >&3
$cat demo_fifo

mkfifo - create named pipe
exec - to a assigned 3 as file descriptor for named pipe
$ls -l >&3  add output of ls -l to named pipe
cat - read the data from named pipe

Following is example of Ordinary pipe:
---------------------------------------------------------------------------------
linux_pipe.c
---------------------------------------------------------------------------------

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

#define BUFFER_SIZE 50
#define READ_END 0
#define WRITE_END 1

int main(int argc, char *argv[]){
char write_msg[BUFFER_SIZE] = "message over pipe";
char read_msg[BUFFER_SIZE];
int file_descriptor[2];

pid_t pid;

// create pipe
if (pipe(file_descriptor) == -1){
fprintf(stderr, "ERROR: Pipe creation failed");
return 1;
}

pid = fork(); // fork process
if (pid < 0){ // process forking failure
fprintf(stderr, "ERROR: Process forking failure");
}
else if (pid == 0){ //this is child process
printf("Inside child process\n");
close(file_descriptor[WRITE_END]); //close the write end of the pipe
read(file_descriptor[READ_END], read_msg, BUFFER_SIZE); //read message from pipe. wait until message is received
printf("Read data = %s", read_msg);
close(file_descriptor[READ_END]); //close read end of the pipe
}
else { //this is parent process
sleep(5); //Too verify child waits at read() for 5sec until it receives message
close(file_descriptor[READ_END]); //close read end of the pipe
write(file_descriptor[WRITE_END], write_msg, strlen(write_msg) + 1); //writing message to pipe
printf("Task of writing message to pipe completed\n");
close(file_descriptor[WRITE_END]); //close write end of the pipe
}

return 0;
}


---------------------------------------------------------------------------------
output
---------------------------------------------------------------------------------

Inside child process

Task of writing message to pipe completed
Read data = message over pipe

Wednesday, April 20, 2016

Clarification on hierarchy.... GTK+, GDB, GLib and GNU C ibrary

GNU C Library(glibc) - wrapper around linux kernel and it communicates to kernel via system calls. Its the implementation of the C standard library.

GLib - It uses GNU C Library to use linux kernel resource. All basic & advanced data structures, thread creation, IPC related & processes can be called through GLib API. It provides Main loop functionality which is used in applications like DBus (GDBus).

GDK(GIMP Drawing Kit) - Its a drawing tool used to communicate to graphical system. It provides API using which we can communicate with display device driver  easily.

GTK+(GIMP Toolkit) Its a UI development toolkit, a level above which is used to design UI for the applications. It makes the code portable from various OS, as the code once written using GTK+, we can cross-compile it to any platform. GNOME linux GUI is built using GTK+.

Now a days, people prefer using Qt, as it provides rich set of APIs to construct beautiful UI and as well as portable from OS to OS and device to device.

IPC: Message queue with example

Message queue

Message queue is a type of inter process communication. It is used to transfer data between processes. It is asynchronous communication as in, sender can dump data in queue, and receiver can get the data out at its convenience.

Parameters of queue:

  1. Queue ID
  2. Key
  3. Message structure:
    • type
    • text

Method calls:

  1. msgget()
  2. msgsnd()
  3. msgrcv()

Applications:

  1. VxWorks and QNX encourage the use of message queue for inter-process & inter-thread communication
  2. It provides resilience functionality as the message dont get "lost" in communication in case of system failure.

Example:

Sender code - creates queue and enter message into it with a particular key
Receiver code - Access the queue, gets the message and prints the text. If while receiver process execution data is not available in queue, it waits at msgrcv(), and proceeds when it gets some data.

Shell command to view the queue IPC
$ipcs -q

*******************************
sender.c
*******************************
/*
 * sender.c
 *
 *  Created on: 19-Apr-2016
 *      Author: root
 */

//IPC_msgq_send.c

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXSIZE     128

void die(char *s)
{
  perror(s);
  exit(1);
}

struct msgbuf
{
    long    mtype;
    char    mtext[MAXSIZE];
};

main()
{
int count = 0;
//char data[3][MAXSIZE] = {"first", "second", "third"};
    int msqid;
    int msgflg = IPC_CREAT | 0666;
    key_t key;
    struct msgbuf sbuf;
    size_t buflen;

    key = 1234;

    if ((msqid = msgget(key, msgflg )) < 0)   //Get the message queue ID for the given key
      die("msgget");

    //Message Type
    sbuf.mtype = 1;

    printf("Enter a message to add to message queue : ");
    scanf("%[^\n]",sbuf.mtext);
    getchar();

    buflen = strlen(sbuf.mtext) + 1 ;

    while (count < 3){
    //*sbuf.mtext = data[count];
    //buflen = strlen(sbuf.mtext) + 1 ;
if (msgsnd(msqid, &sbuf, buflen, IPC_NOWAIT) < 0)
{
printf ("%d, %d, %s, %d\n", msqid, sbuf.mtype, sbuf.mtext, buflen);
die("msgsnd");
}
else
{
printf("Message Sent\n");
}
count++;
    }
    exit(0);
}

*******************************
receiver.c
*******************************
/*
 * receiver.c
 *
 *  Created on: 19-Apr-2016
 *      Author: root
 */

//IPC_msgq_rcv.c

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE     128

void die(char *s)
{
  perror(s);
  exit(1);
}

typedef struct msgbuf
{
    long    mtype;
    char    mtext[MAXSIZE];
} ;


main()
{
    int msqid;
    key_t key;
    struct msgbuf rcvbuffer;

    key = 1234;

    if ((msqid = msgget(key, 0666)) < 0)
      die("msgget()");


     //Receive an answer of message type 1.
    if (msgrcv(msqid, &rcvbuffer, MAXSIZE, 1, 0) < 0)
      die("msgrcv");

    printf("%s\n", rcvbuffer.mtext);
    exit(0);
}

--------------------------------------------------------------------------------------------------

OUTPUT:

$ ipcs -q

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    


$./sender
Enter a message to add to message queue : text data to trasmit
Message Sent
Message Sent
Message Sent

$ ipcs -q

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    
0x000004d2 0          root       666        63           3           

$./receiver
text data to trasmit

$ ipcs -q

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    
0x000004d2 0          root       666        42           2           

$./receiver
text data to trasmit

$ ipcs -q

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    
0x000004d2 0          root       666        21           1           

$./receiver
text data to trasmit

$ ipcs -q

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    
0x000004d2 0          root       666        0            0           


PROFILE

My photo
India
Design Engineer ( IFM Engineering Private Limited )

Followers