LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices



Reply
 
Search this Thread
Old 10-01-2012, 02:37 AM   #1
errigour
Member
 
Registered: May 2009
Posts: 278

Rep: Reputation: 5
C programming game skeleton and fork just don't mix


I'm having a problem with fork, the program should compile with gcc.

Fork doesn't print "ticks." each second like I thought it would. and when I do get fork to print, it just spams the terminal. I want to print a "tick." every second or so.

Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ncurses.h>

struct character_file
{
     char *name;                   /* Character name                       */
     char *password;               /* Character password                   */
     char *description;            /* Character description                */

     short int maxhits;            /* Character hitpoints                  */
     short int maxmana;            /* Character mana                       */
     short int maxmoves;           /* Character moves                      */
     
     short int hits;               /* Character hitpoints                  */
     short int mana;               /* Character mana                       */
     short int moves;              /* Character moves                      */
     
     short int weight;             /* Characters weight                    */
     short int height;             /* Characters height                    */

     short int str;                /* Strength modifier                    */
     short int dex;                /* Dexterity modifier                   */
     short int cha;                /* Charisma modifier                    */
     short int in;                 /* Intelligence modifier                */
     short int wis;                /* Wisdom modifier                      */
     short int con;                /* Constitution modifier                */

     short int thaco;              /* Thaco - ac = d20 needed to hit       */
     short int attack;             /* Attack + d20 >= (thaco - ac) = hit   */
     short int ac;                 /* ac armor class                       */
     short int dr;                 /* dr + damage dice - ac = damage       */

     struct objects *carried;      /* Character objects they carry         */
     struct objects *equipped;     /* Character objects equipped           */
};

struct rooms
{
     short int rnum;               /* Room number                          */

     char *name;                   /* Room name                            */
     char *description;            /* Room description                     */

     char *flags;                  /* Room flags ex: Dark Tunnel noshout   */
     char *types;                  /* Types of rooms Inside Underwateretc. */
     char *exits;                  /* ex: North east south west up down    */

     struct room_data *next;
};

struct objects
{
     char *name;                   /* Object name                          */
     char *description;            /* Object description                   */
     
     short int onum;               /* Unique object number                 */

     short int type;               /* Type of object                       */
     short int weight;             /* Object weight                        */
     short int *flags;             /* Object flags etc: !warrior cursed    */

     struct modifiers *mod;        /* Object modifiers                     */
     struct objects *next;         /* Linked list structure                */
};

struct modifiers
{
     short int maxhits;            /* Max hitpoint modifier                */
     short int maxmana;            /* Max mana point modifier              */
     short int maxmoves;           /* Max move point modifier              */

     short int hit;                /* Hit point modifier                   */
     short int mana;               /* Mana point modifier                  */
     short int moves;              /* Move point modifier                  */
     
     short int weight;             /* Characters weight                    */
     short int height;             /* Characters height                    */
     
     short int thaco;              /* Thaco - ac = d20 needed to hit       */
     short int attack;             /* Attack + d20 >= (thaco - ac) = hit   */
     short int ac;                 /* ac armor class                       */
     short int dr;                 /* dr + damage dice - ac = damage       */
     
     short int str;                /* Strength modifier                    */
     short int dex;                /* Dexterity modifier                   */
     short int cha;                /* Charisma modifier                    */
     short int in;                 /* Intelligence modifier                */
     short int wis;                /* Wisdom modifier                      */
     short int con;                /* Constitution modifier                */
};

struct command_buffer {
     char *buf;
     struct command_buffer *next;
};

void skip_spaces(char **string)
{
  for (; **string && isspace(**string); (*string)++);
}

int main(int argc, char **argv)
{
     pid_t parent_pid;
     pid_t child_pid;

     parent_pid = getpid();

     child_pid = fork();

if ( child_pid == 0)
{
     child_pid = getpid();

     short int j;
     short int second = 0;
     for( j = 0; j <= 500000; j++)
     {
          second++;
          if ( second == 10000)
          {
               printf("Tick.");
               second = 0;
          }
     }
}

if ( getpid() == parent_pid)
{
     printf("Parent: parent_pid: %d,\r\n", parent_pid);
     printf("Parent:  child_pid: %d\r\n", child_pid);
     
     FILE *fp;

     bool quit;

     char ch = 0x00;

     short int x, y;
     short int char_count;
     short int array [10][2] =
     {
     {1,1},
     {2,2},
     {3,3},
     {4,4},
     {5,5},
     {6,6},
     {7,7},
     {8,8},
     {9,9},
     {0,0}
     };

     struct command_buffer *buffer = NULL;
     buffer = malloc(sizeof(buffer));
     buffer->buf = malloc(101);
     buffer->next = NULL;
     struct command_buffer *top = NULL;
     top = buffer;

     for ( x = 0; x < 10; x++)
          printf ("%d: size of array:%d\r\n", array[x][0], sizeof(array));

     if ((fp = fopen("hometown.map", "w+")) == NULL)
          printf("Error opening hometown.map\r\n");

     for ( y = 0; y<= 25; y++)
     {
          for ( x = 0; x <= 50; x++)
          {
               fwrite(".", 1, 1, fp);
               printf(".");
          }
          fwrite("\n", 1, 1, fp);
          printf("\n");
     }
     fclose(fp);

     while ( quit != true )
     {
          int j;
          
          printf("Enter a line of text (<80 chars)\n");
          
          char_count = 0; ch = getchar();
          
          while( ch != '\n')
          {
               if ( char_count < 100)
               {
                    buffer->buf[char_count++] = ch;
               }
               else
               {
                    buffer->buf[char_count] = 0x00;
                    if ( buffer->next == NULL)
                    {
                         buffer->next = malloc(sizeof(buffer->next));
                         buffer->next->buf = malloc(101);
                         buffer = buffer->next;
                         buffer->next = NULL;
                    }
                    else
                         buffer = buffer->next;
                    buffer->buf[0] = ch;
                    char_count = 1;
               }
               ch = getchar();
          }
          ch = 0x00;
          for ( buffer = top; buffer != NULL; buffer = buffer->next)
          {
               for ( j = 0; j < 101; j++)
                    buffer->buf[100] = 0x00;
               if ( buffer->buf[0] != 0x00)
               {
                    if(!strcmp(buffer->buf, "exit"))
                         quit = true;
                    else
                         printf("%s", buffer->buf);
               }
               for ( j = 0; j < 101; j++)
                    buffer->buf[j] = 0x00;
          }
          buffer = top;
          printf("\r\n");
          //printf("quit command didn't work\r\n");
     }

     while ( buffer != NULL)
     {
          top = buffer->next;
          free(buffer);
          buffer = top;
     }
     
     kill(child_pid);
}

     _exit(0);
}
 
Old 10-01-2012, 03:06 AM   #2
pan64
Guru
 
Registered: Mar 2012
Location: Hungary
Distribution: debian i686 (solaris)
Posts: 5,159

Rep: Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364
here you can find a good tutorial: http://www.yolinux.com/TUTORIALS/ForkExecProcesses.html
try to implement 2 functions: parent code and child code and after fork you can call these functions (based on the return value).
instead of the cycle on seconds you would need to use sleep:
while (true) { sleep (1); printf("Tick."); } # or something similar.
 
Old 10-01-2012, 04:16 AM   #3
errigour
Member
 
Registered: May 2009
Posts: 278

Original Poster
Rep: Reputation: 5
Thanks that tick trick worked better then mine. it will starting printing after I'm done looping getchar I think getchar is stopping it's execution. still doesn't print while the other process waits for input.
 
Old 10-01-2012, 12:57 PM   #4
errigour
Member
 
Registered: May 2009
Posts: 278

Original Poster
Rep: Reputation: 5
Hmm tick didnt work actually. some time I get ticks and they don't tick like I want them to. no problem Im gonna have to make it more passive. also global variables don't work for me with fork. but that example uses c++ maybe that will help, but not me.
 
Old 10-01-2012, 01:00 PM   #5
pan64
Guru
 
Registered: Mar 2012
Location: Hungary
Distribution: debian i686 (solaris)
Posts: 5,159

Rep: Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364
I think in this case C or C++ is not important. Also I do not really understand what do you mean by "global variables don't work"
 
Old 10-02-2012, 06:58 AM   #6
errigour
Member
 
Registered: May 2009
Posts: 278

Original Poster
Rep: Reputation: 5
well you cant modify one variable and have the parent process save the variable they kinda work like function variables that you can't return.
 
Old 10-02-2012, 07:09 AM   #7
414N
Member
 
Registered: Sep 2011
Location: Italy
Distribution: Slackware
Posts: 609

Rep: Reputation: 180Reputation: 180
I think you should fflush(stdout) after every printf when using forks, IIRC...
 
Old 10-02-2012, 09:19 AM   #8
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian
Posts: 2,543

Rep: Reputation: 879Reputation: 879Reputation: 879Reputation: 879Reputation: 879Reputation: 879Reputation: 879
Quote:
Originally Posted by 414N View Post
I think you should fflush(stdout) after every printf when using forks, IIRC...
A single fflush (per stream) before the fork() should suffice.

Quote:
Originally Posted by errigour
well you cant modify one variable and have the parent process save the variable they kinda work like function variables that you can't return.
Yes, that is how processes work. Maybe you really want threads?
 
Old 10-03-2012, 12:03 AM   #9
errigour
Member
 
Registered: May 2009
Posts: 278

Original Poster
Rep: Reputation: 5
threads sound promising but Im sure thats c++ and I will have to change alot of malloc calls. Im gonna dang use ncurss and just start passivly checking for input one character at a time I suppose. receving data is easier and you don't need fork either but eventually Ill research c++; so any of you guys can figure this out:
http://www.linuxquestions.org/questi...39#post4795539
also download this and make it work without valgrind whining about null pointer comparisons
http://o0oo0.net16.net/shared
 
Old 10-03-2012, 01:44 AM   #10
pan64
Guru
 
Registered: Mar 2012
Location: Hungary
Distribution: debian i686 (solaris)
Posts: 5,159

Rep: Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364
you can use threads in c as well, not only in c++.
http://www.yolinux.com/TUTORIALS/Lin...ixThreads.html
https://computing.llnl.gov/tutorials/pthreads/
 
Old 10-03-2012, 04:33 AM   #11
errigour
Member
 
Registered: May 2009
Posts: 278

Original Poster
Rep: Reputation: 5
Hey I'm having trouble with threads:
They don't seem to pay attention to my for loops again like fork:
The up side is the variables work interchangably
 
Old 10-03-2012, 05:06 AM   #12
pan64
Guru
 
Registered: Mar 2012
Location: Hungary
Distribution: debian i686 (solaris)
Posts: 5,159

Rep: Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364Reputation: 1364
please show what have you made
 
Old 10-03-2012, 06:21 PM   #13
errigour
Member
 
Registered: May 2009
Posts: 278

Original Poster
Rep: Reputation: 5
Quote:
Originally Posted by pan64 View Post
please show what have you made
Code:
#include <stdio.h>
#include <time.h>
#include <pthread.h>
#include <ncurses.h>

bool quit = false;

void *time_string(void *ptr)
{
     char *message;

     message = (char *) ptr;

     struct tm *str_time;     time_t sec;    int j;

     while( quit == false)
          for (j = 0; j <= 500000; j++)
          if ( (j % 50000) == 0)
          {
          sec = time (NULL);

          printf("%s \n", message);
          printf("\tNumber of hours since January 1, 1970 is %ld\r\n\r\n", sec/3600);
          printf("\tUnix Time: %s\r\n", ctime(&sec)); str_time = gmtime ( &sec );
          printf("\tstruct tm *str_time\r\n");
          printf("\tstr_time->tm_sec       : %d\r\n", str_time->tm_sec);
          printf("\tstr_time->tm_min       : %d\r\n", str_time->tm_min);
          printf("\tstr_time->tm_hour      : %d\r\n", str_time->tm_hour);
          printf("\tstr_time->tm_mday      : %d\r\n", str_time->tm_mday);
          printf("\tstr_time->tm_mon       : %d\r\n", str_time->tm_mon);
          printf("\tstr_time->tm_year      : %d\r\n", str_time->tm_year);
          printf("\tstr_time->tm_wday      : %d\r\n", str_time->tm_wday);
          printf("\tstr_time->tm_yday      : %d\r\n", str_time->tm_yday);
          printf("\tstr_time->tm_isdst     : %d\r\n", str_time->tm_isdst);
#ifdef      __USE_BSD
          printf("\tlong int tm_gmtoff     : %d\r\n", str_time->tm_gmtoff);
          printf("\t__const char *tm_zone  : %d\r\n", str_time->tm_zone);
          printf("\t__USE_BSD              : defined\r\n");
#else
          printf("\tlong int __tm_gmtoff   : %d\r\n", str_time->__tm_gmtoff);
          printf("\t__const char *__tm_zone: %d\r\n\r\n\r\n\r\n\r\n", str_time->__tm_zone);
#endif
          }
}

int main()
{
     pthread_t time_thread;
     char *message = "This is the time thread.";
     pthread_create( &time_thread, NULL, time_string, (void *) message);
     getchar();
     quit = true;

}
 
Old 10-04-2012, 03:49 AM   #14
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: FreeBSD, Debian, Mint, Puppy
Posts: 3,314

Rep: Reputation: 175Reputation: 175
I don't think fork is a good method of achieving your aim. A fork is a different process
where logically your 'tick' is part of the same mass.

There already exists a method for interval processing: interval timer

Unfortunately the is very little documentation or example for it,

Here is an example I knocked up if you are interested:

You need to link pthread and realtime libraries.
g++ -lrt -lpthread timer.cpp -o timer

Code:
/*
 * (c) bigearsbilly
 *
 *    need LDLIBS =  -lrt -lpthread
 */
#include <pthread.h>
#include <signal.h>
#include <sys/time.h>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <iostream>
#include <iomanip>

using std::cout;
using std::cerr;
using std::endl;

typedef void (timer_callback) (union sigval);

int set_timer(timer_t * timer_id, float delay, float interval, timer_callback * func, void * data)
{
    int status =0;
    struct itimerspec ts;
    struct sigevent se;

    se.sigev_notify = SIGEV_THREAD;
    se.sigev_value.sival_ptr = data;
    se.sigev_notify_function = func;
    se.sigev_notify_attributes = NULL;

    status = timer_create(CLOCK_REALTIME, &se, timer_id);

    ts.it_value.tv_sec = abs(delay);
    ts.it_value.tv_nsec = (delay-abs(delay)) * 1e09;
    ts.it_interval.tv_sec = abs(interval);
    ts.it_interval.tv_nsec = (interval-abs(interval)) * 1e09;

    status = timer_settime(*timer_id, 0, &ts, 0);
    return 0;
}

void callback(union sigval si)
{
    char * msg = (char *) si.sival_ptr;
    std::cout << msg << std::endl;
}

int main(int argc, char ** argv)
{

    timer_t tick;
    timer_t tock;
    set_timer(&tick, 1, 1, callback, (void *) "tick" );
    set_timer(&tock, 1.5, 1, callback, (void *) "tock" );
    getchar();

    return 0;
}
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
LXer: Why free software and Apple's iPhone don't mix LXer Syndicated Linux News 0 07-31-2008 05:20 AM
LXer: Gp2x Adds Linux Flavor to Game Console Mix LXer Syndicated Linux News 0 12-03-2006 12:54 AM
samba, printing and windows just don't mix hotrodowner Linux - Networking 2 05-10-2005 09:58 PM
ICS and 302 redirects don't mix dataangel Linux - Networking 1 08-22-2004 03:36 PM
firebird and thunderbird don't mix? jaan kaer Linux - Newbie 2 11-23-2003 03:45 PM


All times are GMT -5. The time now is 05:28 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration