<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>High Fibre Programming &#187; C</title>
	<atom:link href="http://www.4pmp.com/category/c/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.4pmp.com</link>
	<description>PHP, MySQL, C, Java, Linux and other great after dinner speech topics</description>
	<lastBuildDate>Thu, 08 Jul 2010 07:35:30 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Multitasking: PHP in parallel</title>
		<link>http://www.4pmp.com/2010/03/multitasking-php-in-parallel/</link>
		<comments>http://www.4pmp.com/2010/03/multitasking-php-in-parallel/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 22:03:13 +0000</pubDate>
		<dc:creator>Nick</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[multitasking]]></category>
		<category><![CDATA[multithreading]]></category>
		<category><![CDATA[wrapper]]></category>

		<guid isPermaLink="false">http://www.4pmp.com/?p=257</guid>
		<description><![CDATA[Like most websites, glogster.com periodically sends out an e-newsletter to its user-base.      This is done by a simple PHP script that opens a socket to a mail server and goes through the user database, sending an email to each one.      This approach has worked fine until recently, the number of users [...]]]></description>
			<content:encoded><![CDATA[<p>Like most websites, glogster.com periodically sends out an e-newsletter to its user-base.      This is done by a simple PHP script that opens a socket to a mail server and goes through the user database, sending an email to each one.      This approach has worked fine until recently, the number of users has gone up dramatically and now it takes an infeasibly long time to send emails to all our users.</p>
<p>After optimising the script as much as possible, the only alternative option was to run many instances of the script simultaneously.   PHP doesn&#8217;t support multithreading, and although PHP does support POSIX style process control ( <a title="PHP PCNTL Documentation" href="http://www.php.net/manual/en/book.pcntl.php">http://www.php.net/manual/en/book.pcntl.php</a> ) I decided to create a wrapper in C that would handle multiple instances of PHP.   <em>(I haven&#8217;t found anything technically wrong with PHP&#8217;s process control, I just needed something stable, reliable and potentially able to mulitask other scripts such as Python).</em></p>
<h4>How it works<em><br />
</em></h4>
<p>The wrapper I made (see below for code listing) is fairly simple and works by creating a series of threads, each of which forks and creates a PHP instance (replacing the child process) that runs the emailing script.   The thread from the parent process waits for the PHP process to finish and then ends itself.   Once a thread ends, the main thread creates another one, thereby maintaining a constant number of threads.   Signal handling is handled by a separate thread and can either tell the main thread to stop creating new threads and thereby safely shutdown the program or directly terminate all child processes and thus abruptly end the program.</p>
<h4>Almost done</h4>
<p>So now I had a way of running any number of PHP processes simultaneously and was almost ready to send emails at lightning speed, however one problem remained.   Once an email has been sent to a user, the database is updated so that I know which user has received which email and thus prevent me from sending the same user the same email more than once.   The problem is; what if one instance of the PHP script reads a user, and before it has time to send them the email and update the database, another PHP instance reads the same user and also sends them the email?   One way to solve this would be through locking the database table before reading and updating each row, however this would slow the database down which is not ideal.</p>
<p>The solution I came up with was to limit the number of simultaneous PHP instances to 8 and have the wrapper send each PHP process a unique instance ID from 0 to 7.   When selecting users from the database, the script looked at the 3 least significant bits (LSBs) of the IDs in the recipients table and selected only those rows whose 3 LSBs equated to the instance ID passed from the wrapper.</p>
<pre class="brush: sql; gutter: false;">SELECT *,
(
	if( (`id` | 1) = `id`, 1, 0) +
	if( (`id` | 2) = `id`, 2, 0) +
	if( (`id` | 4) = `id`, 4, 0)
) AS `IID`
FROM `recipients`
WHERE `sent` = 0
HAVING `IID` = :IID
LIMIT :OFFSET, :BATCH_SIZE;
</pre>
<p>Just bind the instance ID passed from the wrapper into the query and each instance will now select recipients that are unique to that ID &#8211; no two concurrent instances can select the same recipients.   Just don&#8217;t forget to update each row once each email has been sent.</p>
<p><strong>Note:</strong> <em>Using OFFSET in a limit clause is inefficient, for an alternative: <a href="http://www.4pmp.com/2010/02/scalable-mysql-avoid-offset-for-large-tables/">http://www.4pmp.com/2010/02/scalable-mysql-avoid-offset-for-large-tables/</a></em> </p>
<h4>Finishing touches</h4>
<p>We&#8217;re almost there, just one more little feature is required and the system will be perfect (sort of).   If a thread process has nothing to do then it will return immediately, so we end up with a situation when thread processes are constantly created and destroyed which is not the most efficient use of resources.   The solution was to check the <a href="http://en.wikipedia.org/wiki/Exit_status">exit status</a> of the PHP process.   If zero then all is ok, the thread ends and is available to be restarted immediately as normal.   If however, the exit status is non-zero then the thread is marked as &#8220;sleeping&#8221; and cannot be restarted by the main thread for another 30 seconds.   </p>
<p>If the PHP script doesn&#8217;t find any rows in the database to process then it returns 250 (a non-zero, non-reserved exit status) and so the calling thread in the wrapper sleeps for 30 seconds before trying again to see if there are any new items in the database to process.</p>
<p>This has the added advantage that if anything goes wrong in the PHP script, such as a fatal error, then the thread will sleep and you won&#8217;t end up with perpetuate thread cycling.</p>
<h4>Code listing</h4>
<p>Here is the code for the wrapper.   The code should be fairly straightforward, with the above notes and the inline comments you should be able to figure out what&#8217;s going on &#8211; just don&#8217;t forget to compile with the pthread library.   Comments are of course very welcome!</p>
<pre class="brush: cpp;">
#include &lt;pthread.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;signal.h&gt;
#include &lt;errno.h&gt;
#include &lt;sys/wait.h&gt;

#define NUM_THREADS 8
#define THREAD_STACK_HEADROOM 1048576

pthread_mutex_t mutexSignal;
int slots[NUM_THREADS];
int handledSignal = -1;

void* signalHandler(void* arg);
void waitForThreads();
void killall();
void *task(void *i);

/**
 * Each thread will do this
 *
 */
void *task(void *i)
{
    sigset_t signalSet;
    int iid;
    char *tid;
    int stat_loc;

    iid = (int)i;

    /* Say hello and show the thread number */
    printf(&quot;Thread %d: starting\n&quot;, iid);

    /* Spawn a child to run the program. */
    pid_t pid=fork();

    switch (pid)
    {
        case 0:
            setsid();
            sigfillset(&amp;signalSet);
            pthread_sigmask(SIG_UNBLOCK, &amp;signalSet, NULL );

            tid = malloc(11*sizeof(char));

            sprintf(tid, &quot;tid=%d&quot;, iid);

            char *argv[]={&quot;php&quot;, &quot;./sleep.php&quot;, tid, NULL};

            execv(&quot;/usr/bin/php&quot;,argv);
            free(tid);
            exit(EXIT_FAILURE); /* only if execv fails */
        case -1:
            printf(&quot;Thread %d: Fork failed\n&quot;, iid);
            slots[iid] = 0;
            break;
        default:
            /*  parent process */
            slots[iid] = pid;

            if (pid == waitpid(pid,&amp;stat_loc,WUNTRACED)) /* wait for child to exit */
            {
                printf(&quot;Thread %d: Child finished with exit code: %d&quot;, iid, WEXITSTATUS(stat_loc));

                if (WEXITSTATUS(stat_loc) != 0)
                {
                    /* Sleep this thread, set available time to now+30s */
                    printf(&quot; Going to sleep\n&quot;);
                    slots[iid] = -1 * (time(0) + 30);
                }
                else
                {
                    /* Free this thread slot */
                    printf(&quot; Returning to pool\n&quot;);
                    slots[iid] = 0;
                }
            }
            else
            {
                printf(&quot;Thread %d: Bad exit\n&quot;, iid);
                slots[iid] = 0;
            }
    }

    printf(&quot;Thread %d: Finished\n&quot;, iid);

    /* Terminate the thread */
    pthread_exit((void*) i);
}

void killall()
{
    int kv,i;

    for (i=0; i&lt;NUM_THREADS;i++)
    {
        kv = kill(slots[i], SIGINT);
        printf(&quot;Killed %d: %s\n&quot;, slots[i], kv ==0?&quot;ok&quot;:&quot;fail&quot;);
    }
}

void waitForThreads()
{
    int i, stoppedThreads;

    printf(&quot;Waiting for threads to finish\n&quot;);

    while(1)
    {
        stoppedThreads = 0;

        for (i=0; i&lt;NUM_THREADS;i++)
        {
            /* Check if thread has finished or is sleeping */
            if (slots[i] == 0 || slots[i] &lt; -1)
            {
                stoppedThreads++;
            }
        }

        if (stoppedThreads == NUM_THREADS)
        {
            break;
        }
    }
}

void* signalHandler( void* arg )
{
    sigset_t signal_set;
    int sig;

    while (1)
    {
        /* Wait for any and all signals */
        sigfillset(&amp;signal_set);

        sigwait(&amp;signal_set, &amp;sig);

        /* When we get this far, we've caught a signal */

        switch(sig)
        {
            /* SIGQUIT */
            case SIGTERM:
            case SIGQUIT:
                pthread_mutex_lock(&amp;mutexSignal);
                handledSignal = SIGQUIT;
                pthread_mutex_unlock(&amp;mutexSignal);
                break;

            /* SIGINT */
            case SIGINT:
                pthread_mutex_lock(&amp;mutexSignal);
                handledSignal = SIGINT;
                pthread_mutex_unlock(&amp;mutexSignal);
                break;

            /* other signals */
            default:
                pthread_mutex_lock(&amp;mutexSignal);
                handledSignal = 0;
                pthread_mutex_unlock(&amp;mutexSignal);
                break;
        }
    }

    return (void*)0;
}

/**
 * Main
 *
 */
int main()
{
    int rc, i;
    int running = 1;
    size_t stacksize;
    sigset_t signalSet;
    pthread_t threadSignalHandler;
    pthread_t thread[NUM_THREADS];
    pthread_attr_t attr;

    /* Initialise the signal mutex lock */
    pthread_mutex_init(&amp;mutexSignal, NULL);

    /* Initialise and set thread attributes */
    pthread_attr_init(&amp;attr);
    //pthread_attr_setdetachstate(&amp;attr, PTHREAD_CREATE_JOINABLE);
    pthread_attr_setdetachstate(&amp;attr, PTHREAD_CREATE_DETACHED);

    /* Ensure each thread has a given stack size - portability */
    pthread_attr_getstacksize(&amp;attr, &amp;stacksize);
    printf(&quot;Default stack size = %li\n&quot;, (long) stacksize);

        /* Determine and set a new stack size */
        stacksize = sizeof(sigset_t) + THREAD_STACK_HEADROOM;
        printf(&quot;Amount of stack calculated per thread = %li\n&quot;, (long) stacksize);
        pthread_attr_setstacksize (&amp;attr, stacksize);

    /* block all signals */
    sigfillset(&amp;signalSet);
    pthread_sigmask(SIG_BLOCK, &amp;signalSet, NULL );

    /* create the signal handling thread */
    pthread_create(&amp;threadSignalHandler, NULL, signalHandler, NULL);

    while (running &gt; 0)
    {
        /* Find an empty slot */
        for (i=0; i&lt;NUM_THREADS;i++)
        {
            if (slots[i] == 0)  /* Thread is currently not doing anything, so let's give it something to do */
            {
                /* Set this slot as used, -1 is a temporary value before being replaced by the PID of the forked process (prevents race hazards) */
                slots[i] = -1;

                /* This slot is spare */
                printf(&quot;Main: creating thread %d\n&quot;, i);

                /* Create a new thread */
                rc = pthread_create(&amp;thread[i], &amp;attr, task, (void *)i);

                if (rc)
                {
                    printf(&quot;ERROR: return code from pthread_create() is %d\n&quot;, rc);
                    exit(1);
                }

                break;
            }
            else if (slots[i] &lt; -1)     /* Thread is sleeping, see if we should wake it up */
            {
                if (time(0) &gt; (-1 * slots[i]) )
                {
                    /* Thread has slept long enough so let's wake it up */
                    slots[i] = 0;
                }
            }
        }

        pthread_mutex_lock(&amp;mutexSignal);

        switch ( handledSignal )
        {
            case -1:
                break;

            case 0:
                /* The case for signals we're not interested in */
                handledSignal = -1;
                break;

            case SIGTERM:
            case SIGQUIT:
                printf(&quot;Main: SIGQUIT\n&quot;);
                handledSignal = -1;
                running = -1;
                killall();
                break;

            case SIGINT:
                printf(&quot;Main: SIGINT\n&quot; );
                handledSignal = -1;
                running = -1;
                break;
        }

        pthread_mutex_unlock(&amp;mutexSignal);

        /* Sleep for a bit - all this thread creation is hard work! */
        usleep(100000);
    }

    waitForThreads();

    printf(&quot;Bye\n&quot;);
}
</pre>
<p>And here&#8217;s a sample PHP script (but you can of course have the wrapper call anything).</p>
<pre class="brush: php;">
&lt;?php

list($junk, $tid) = explode(&quot;=&quot;, $argv[1], 2);

printf(&quot;PHP: Hello from thread %d\n&quot;, $tid);

sleep(mt_rand(4,14));

// Non-zero exit status if the calling thread should sleep
// Chosen 250 because it's not a reserved status
// NOTE: PHP returns 255 on fatal error
exit(250);
</pre>
<h4>Exercises left to the reader</h4>
<p>The above code is not really intended as production-ready, (although I have actually used it in production) and there are still plenty of loose ends that could do with tidying up.   One thing you might want to do is detach the child PHP processes from the parent process&#8217; output sockets, thereby effectively sending them to the background.   For inspiration take a look at this basic daemonising program: <a href="http://www.4pmp.com/2009/12/a-simple-daemon-in-c/">A simple daemon in C</a>.</p>
<p>Another nice addition might be to allow the child process to be specified in command line arguments to the wrapper.   It would be useful to specify the sleep time for threads and also the maximum number of concurrent threads &#8211; this way you wouldn&#8217;t have to recompile each time you changed something.</p>
<p>If you find this useful or interesting then comments would be greatly welcomed!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.4pmp.com/2010/03/multitasking-php-in-parallel/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A Simple Daemon in C</title>
		<link>http://www.4pmp.com/2009/12/a-simple-daemon-in-c/</link>
		<comments>http://www.4pmp.com/2009/12/a-simple-daemon-in-c/#comments</comments>
		<pubDate>Thu, 10 Dec 2009 08:33:54 +0000</pubDate>
		<dc:creator>Nick</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[daemon]]></category>
		<category><![CDATA[fork]]></category>
		<category><![CDATA[periodically]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[signal handler]]></category>
		<category><![CDATA[signals]]></category>
		<category><![CDATA[thread]]></category>

		<guid isPermaLink="false">http://www.4pmp.com/?p=209</guid>
		<description><![CDATA[A daemon is a process which runs in the background of your computer, periodically carrying out a specific task.   The following is an example of a simple daemon written in C.   It works by forking to create a child process, the parent then terminates but the child carries on in the [...]]]></description>
			<content:encoded><![CDATA[<p>A daemon is a process which runs in the background of your computer, periodically carrying out a specific task.   The following is an example of a simple daemon written in C.   It works by forking to create a child process, the parent then terminates but the child carries on in the background &#8211; entering a continuous loop of doing a task and then sleeping.   The child process is of course an identical copy of the parent so care must be taken to close all file descriptors, thus detaching the child completely from the calling process.   The deamonised process is controlled by sending it signals which it can catch and take action accordingly.   In the example below, the process is terminated by sending SIGINT or SIGTERM, but you can of course add in your own handling &#8211; for example to re-read config data on SIGHUP.</p>
<pre class="brush: cpp;">
#include &lt;stdio.h&gt;
#include &lt;signal.h&gt;
#include &lt;syslog.h&gt;
#include &lt;errno.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;unistd.h&gt;
#include &lt;string.h&gt;

#define DAEMON_NAME &quot;simpledaemon&quot;

    void daemonShutdown();
    void signal_handler(int sig);
    void daemonize(char *rundir, char *pidfile);

    int pidFilehandle;

    void signal_handler(int sig)
    {
        switch(sig)
        {
            case SIGHUP:
                syslog(LOG_WARNING, &quot;Received SIGHUP signal.&quot;);
                break;
            case SIGINT:
            case SIGTERM:
                syslog(LOG_INFO, &quot;Daemon exiting&quot;);
                daemonShutdown();
                exit(EXIT_SUCCESS);
                break;
            default:
                syslog(LOG_WARNING, &quot;Unhandled signal %s&quot;, strsignal(sig));
                break;
        }
    }

    void daemonShutdown()
    {
        close(pidFilehandle);
    }

    void daemonize(char *rundir, char *pidfile)
    {
        int pid, sid, i;
        char str[10];
        struct sigaction newSigAction;
        sigset_t newSigSet;

        /* Check if parent process id is set */
        if (getppid() == 1)
        {
            /* PPID exists, therefore we are already a daemon */
            return;
        }

        /* Set signal mask - signals we want to block */
        sigemptyset(&amp;newSigSet);
        sigaddset(&amp;newSigSet, SIGCHLD);  /* ignore child - i.e. we don't need to wait for it */
        sigaddset(&amp;newSigSet, SIGTSTP);  /* ignore Tty stop signals */
        sigaddset(&amp;newSigSet, SIGTTOU);  /* ignore Tty background writes */
        sigaddset(&amp;newSigSet, SIGTTIN);  /* ignore Tty background reads */
        sigprocmask(SIG_BLOCK, &amp;newSigSet, NULL);   /* Block the above specified signals */

        /* Set up a signal handler */
        newSigAction.sa_handler = signal_handler;
        sigemptyset(&amp;newSigAction.sa_mask);
        newSigAction.sa_flags = 0;

            /* Signals to handle */
            sigaction(SIGHUP, &amp;newSigAction, NULL);     /* catch hangup signal */
            sigaction(SIGTERM, &amp;newSigAction, NULL);    /* catch term signal */
            sigaction(SIGINT, &amp;newSigAction, NULL);     /* catch interrupt signal */

        /* Fork*/
        pid = fork();

        if (pid &lt; 0)
        {
            /* Could not fork */
            exit(EXIT_FAILURE);
        }

        if (pid &gt; 0)
        {
            /* Child created ok, so exit parent process */
            printf(&quot;Child process created: %d\n&quot;, pid);
            exit(EXIT_SUCCESS);
        }

        /* Child continues */

        umask(027); /* Set file permissions 750 */

        /* Get a new process group */
        sid = setsid();

        if (sid &lt; 0)
        {
            exit(EXIT_FAILURE);
        }

        /* close all descriptors */
        for (i = getdtablesize(); i &gt;= 0; --i)
        {
            close(i);
        }

        /* Route I/O connections */
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);

        chdir(rundir); /* change running directory */

        /* Ensure only one copy */
        pidFilehandle = open(pidfile, O_RDWR|O_CREAT, 0600);

        if (pidFilehandle == -1 )
        {
            /* Couldn't open lock file */
            syslog(LOG_INFO, &quot;Could not open PID lock file %s, exiting&quot;, pidfile);
            exit(EXIT_FAILURE);
        }

        /* Try to lock file */
        if (lockf(pidFilehandle,F_TLOCK,0) == -1)
        {
            /* Couldn't get lock on lock file */
            syslog(LOG_INFO, &quot;Could not lock PID lock file %s, exiting&quot;, pidfile);
            exit(EXIT_FAILURE);
        }

        /* Get and format PID */
        sprintf(str,&quot;%d\n&quot;,getpid());

        /* write pid to lockfile */
        write(pidFilehandle, str, strlen(str));
    }

    int main()
    {
        /* Debug logging
        setlogmask(LOG_UPTO(LOG_DEBUG));
        openlog(DAEMON_NAME, LOG_CONS, LOG_USER);
        */

        /* Logging */
        setlogmask(LOG_UPTO(LOG_INFO));
        openlog(DAEMON_NAME, LOG_CONS | LOG_PERROR, LOG_USER);

        syslog(LOG_INFO, &quot;Daemon starting up&quot;);

        /* Deamonize */
        daemonize(&quot;/tmp/&quot;, &quot;/tmp/daemon.pid&quot;);

        syslog(LOG_INFO, &quot;Daemon running&quot;);

        while (1)
        {
            syslog(LOG_INFO, &quot;daemon says hello&quot;);

            sleep(1);
        }
    }
</pre>
<p>The above example is only simple but it serves as a good starting point to create your own daemon.   In my next article I will demonstrate how it can be extended to periodically call a PHP script.</p>
<p>If I find enough time I will also demonstrate how it can be extended from being a single-threaded daemon to a multi-threaded daemon, maintaining a continuous pool of x threads, each doing a given task.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.4pmp.com/2009/12/a-simple-daemon-in-c/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linked Lists in C: push, pop, shift and unshift</title>
		<link>http://www.4pmp.com/2009/10/linked-lists-in-c-push-pop-shift-and-unshift/</link>
		<comments>http://www.4pmp.com/2009/10/linked-lists-in-c-push-pop-shift-and-unshift/#comments</comments>
		<pubDate>Thu, 22 Oct 2009 06:30:19 +0000</pubDate>
		<dc:creator>Nick</dc:creator>
				<category><![CDATA[C]]></category>
		<category><![CDATA[add]]></category>
		<category><![CDATA[download]]></category>
		<category><![CDATA[example]]></category>
		<category><![CDATA[FIFO]]></category>
		<category><![CDATA[free]]></category>
		<category><![CDATA[heap]]></category>
		<category><![CDATA[leak]]></category>
		<category><![CDATA[LIFO]]></category>
		<category><![CDATA[linked]]></category>
		<category><![CDATA[list]]></category>
		<category><![CDATA[malloc]]></category>
		<category><![CDATA[management]]></category>
		<category><![CDATA[memory]]></category>
		<category><![CDATA[node]]></category>
		<category><![CDATA[pop]]></category>
		<category><![CDATA[push]]></category>
		<category><![CDATA[queue]]></category>
		<category><![CDATA[remove]]></category>
		<category><![CDATA[shift]]></category>
		<category><![CDATA[stack]]></category>
		<category><![CDATA[struct]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[unshift]]></category>

		<guid isPermaLink="false">http://www.4pmp.com/?p=135</guid>
		<description><![CDATA[A sound understanding of linked lists and how to use them is a prerequisite for programming in C, or indeed most programming languages for that matter.   Most scripting languages provide built-in helper functions for dealing with arrays and linked lists, C on the other hand doesn&#8217;t &#8211; so you have to do it yourself.   Luckily [...]]]></description>
			<content:encoded><![CDATA[<p>A sound understanding of linked lists and how to use them is a prerequisite for programming in C, or indeed most programming languages for that matter.   Most scripting languages provide built-in helper functions for dealing with arrays and linked lists, C on the other hand doesn&#8217;t &#8211; so you have to do it yourself.   Luckily though, there&#8217;s really not that much to it, but if you&#8217;re new to C then it might be quite daunting to realise you&#8217;re in the deep end with no arm bands!</p>
<p>There are plenty of great books and online tutorials that cover the topic very well, however personally I prefer to look at working examples and so I have created a few for those who are already aware of the theory and want to get on with programming.</p>
<p>All of the examples in this tutorial use a fairly simple struct for linked list nodes containing just a pointer to an integer and the next node in the list.   <em>(You can of course change your nodes to better suit your requirements, but you will have to change the helper functions a bit to reflect this.)</em></p>
<p>It should be fairly simple to figure out what what&#8217;s going on from the inline comments, so I&#8217;ll stop waffling now and get on with the code!</p>
<h4>Node</h4>
<p>Here is the struct that defines each item in the list.</p>
<pre class="brush: cpp;">
struct node
{
    int val;
    struct node *next;
};
</pre>
<p>Note that I have decided to store each item&#8217;s data as an integer, but you can of course choose other types so long as you alter the functions below to accommodate this type.   Basically, the struct can be whatever so long as it has a pointer to the next item in the list.</p>
<h4>Push</h4>
<p>Creates a new node and add it onto the end of the list.</p>
<pre class="brush: cpp;">
/**
 * Adds a node onto the end of the list
 *
 */
void push(struct node** item, int data)
{
    struct node *current;
    struct node *endItem;

    current = *item;

    /* See if the passed value is a node */
    if (current)
    {
        /* See if this is the last node in the list */
        if (current-&gt;next == NULL)
        {
            /* This is the last item, so create a new node to go on the end */

            /* Allocate memory for the new node */
            endItem = malloc(sizeof(struct node));

            /* Set the value */
            endItem-&gt;val = data;

            /* Set the pointer to the next item to be NULL (there isn't a next, this will be the last item) */
            endItem-&gt;next  = NULL;

            /* Set the next pointer in the last item to the new item, making the new item now the last one */
            current-&gt;next = endItem;

            return;
        }
        else
        {
            /* This is not the last item, recurse to the next one */
            return push(&amp;current-&gt;next, data);
        }
    }

    /* There are no nodes in the list, so create a new node and it will be the first in the list */
    endItem = malloc(sizeof(struct node));

    /* Set the value */
    endItem-&gt;val = data;

    /* Set the pointer to the next item to be NULL (there isn't a next, this will be the last item) */
    endItem-&gt;next  = NULL;

    /* Set the passed pointer to point to the new node */
    *item = endItem;
}
</pre>
<h4>Pop</h4>
<p>Removes the last node from the end of the list and return its value.</p>
<pre class="brush: cpp;">
/**
 * Remove the last item and return the value
 *
 */
int pop (struct node **item, int *p)
{
    struct node *current;

    current = *item;

    if (current)
    {
        /* See if the current item specifies a proceding item */
        if (current-&gt;next)
        {
            /* There is a next item, so see if it is the last one */
            if (current-&gt;next-&gt;next == NULL)
            {
                /* The next item is the last one, so get its value */
                *p = current-&gt;next-&gt;val;

                /* Free the memory reserved for the last item */
                free(current-&gt;next);

                /* Remove the pointer to the last item */
                current-&gt;next = NULL;

                return 0;
            }

            /* Move on to the next item */
            return pop(&amp;current-&gt;next, p);
        }

        /* There aren't any more items, this is the last one and therefore also the first */
        *p = current-&gt;val;

        /* Release the memory reserved for it */
        free(*item);

        /* Set the head node to NULL */
        *item = NULL;

        return 0;
    }

    /* There are no items in the list */
    p = NULL;

    return -1;
}
</pre>
<h4>Shift</h4>
<p>Removes the first element from the list and return its value.</p>
<pre class="brush: cpp;">
/**
 * Remove the first item in the list
 *
 */
int shift(struct node **head, int *p)
{
    struct node *firstNode;

    firstNode = *head;

    /* See if there is a first node */
    if (firstNode == NULL)
    {
        /* There isn't, so return -1*/
        return -1;
    }

    /* Set the passed pointer, the pointer to the first node in the list, to the next node */
    *head = firstNode-&gt;next;

    /* Get the value from the first node before we free() it */
    *p = firstNode-&gt;val;

    /* Deallocate the first node */
    free(firstNode);

    /* Return 0, all ok */
    return 0;
}
</pre>
<h4>Unshift</h4>
<p>Creates a new node and add it onto the beginning of the list.</p>
<pre class="brush: cpp;">
/**
 * Add a node onto the beginning of the list
 *
 */
void unshift(struct node** head, int data)
{
    /* Declare and reserve memory for the new item */
    struct node* newNode = malloc(sizeof(struct node));

    /* Se the new node's value */
    newNode-&gt;val = data;

    /* Set the next item to be the item that was previously first */
    newNode-&gt;next = *head;

    /* Set the pointer to the first item to this new item */
    *head = newNode;
}
</pre>
<h5>Things to bear in mind</h5</p>
<p>If you're used to languages such as Java or PHP, you'll know there's no need to tidy up after yourself - afterall, that's what the Garbage Collector is for!   Once you're finished with a variable, just remove all references to it and the memory allocated to it will be magically freed to be use again.   In C there is no such thing, and so you have to be a bit more responsible about the mess you make and clean up afterwards, otherwise your program will run wild and the system administrator will come and bash you over the head, (probably with a large book about memory management).</p>
<p>You might have noticed that in the functions <em>pop()</em> and <em>shift()</em>, there is a call to <em><a title="free()" href="http://www.opengroup.org/onlinepubs/009695399/functions/free.html">free()</a></em> on the node we are removing.   <em>Free()</em> does exactly what it says on the tin; it frees the memory reserved for the variable addressed by the the pointer it is passed.   Note that before we create a new node, we must first allocate memory for it by calling <em><a title="malloc()" href="http://www.opengroup.org/onlinepubs/009695399/functions/free.html">malloc()</a></em>.   <em>Free() </em>deallocates this space so that the process can re-use it again in the future.   If we didn&#8217;t call <em>free()</em> then we would have to keep using more and memory to store new nodes in, which could soon get out of hand if you create and delete lots of nodes.</p>
<h5>So how do we make sure we&#8217;re not eating memory?</h5>
<p>I made a simple function (see below) that continuously adds and then removes nodes onto and from the list &#8211; if we are correctly freeing memory then we should see that the memory used by the program when run will be stable.</p>
<pre class="brush: cpp;">
int main()
{
    struct node *head;
    int i, j;

    head = NULL;

    while (1)
    {

        for (i=1;i&lt;6;i++)
        {
            /* Add to the beginning */
            unshift(&amp;head, i);
            printf(&quot;Unshift: %d\n&quot;, i);
        }

        for (i=6;i&lt;11;i++)
        {
            /* Add to the end */
            push(&amp;head, i);
            printf(&quot;Push: %d\n&quot;, i);
        }

        for (i=1;i&lt;6;i++)
        {
            /* Remove from the end */
            if (pop(&amp;head, &amp;j) == 0)
            {
                printf(&quot;Pop: %d\n&quot;, j);
            }
        }

        for (i=1;i&lt;6;i++)
        {
            /* Remove from the beginning */
            if (shift(&amp;head, &amp;j) == 0)
            {
                printf(&quot;Shift: %d\n&quot;, j);
            }
        }

        /* Functions in a different order */

        for (i=1;i&lt;6;i++)
        {
            /* Add to the end */
            push(&amp;head, i);
            printf(&quot;Push: %d\n&quot;, i);
        }

        for (i=6;i&lt;11;i++)
        {
            /* Add to the beginning */
            unshift(&amp;head, i);
            printf(&quot;Unshift: %d\n&quot;, i);
        }

        for (i=1;i&lt;6;i++)
        {
            /* Remove from the beginning */
            if (shift(&amp;head, &amp;j) == 0)
            {
                printf(&quot;Shift: %d\n&quot;, j);
            }
        }

        for (i=1;i&lt;6;i++)
        {
            /* Remove from the end */
            if (pop(&amp;head, &amp;j) == 0)
            {
                printf(&quot;Pop: %d\n&quot;, j);
            }
        }
    }

    return 0;
}
</pre>
<p><strong>Compile:</strong><br />
<code>gcc llist.c -ollist</code></p>
<p><strong>Don&#8217;t forget rights</strong><br />
<code>chmod +x llist</code></p>
<p><strong>Run:</strong><br />
<code>./llist</code></p>
<p>Now, in another terminal we can watch how much memory the program is running:<br />
<code>watch 'ps aux | grep llist'</code></p>
<p><strong>Just for fun</strong><br />
Comment one of the <em>free()</em> calls from either <em>pop()</em> or <em>shift()</em>, recompile, run and watch the new program.   You should see the memory it is using steadily inrease.</p>
<h5>Download:</h5>
<p>Here&#8217;s a file containing all of the above functions and the test.<br />
<a href='http://www.4pmp.com/wp-content/uploads/2009/10/llist.c'>Linked List Tutorial v1.0</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.4pmp.com/2009/10/linked-lists-in-c-push-pop-shift-and-unshift/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
