I'm trying to compare when does a given date corresponds to current time, when that happens it's supposed to execute a program. I have used an infinite loop so that it waits for the given time to correspond to the current time, the problem is that when that happens it executes the program more than one time and I don't know how to solve this...
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int taskexecution()
{
char * path;
path = "/home/soraia/mieti/Proj/makefile";
pid_t fk = fork();
if (!fk) { /* in child */
chdir("/home/soraia/mieti/Proj");
execlp ("make", "make", "-f", path , NULL);
_exit(127);
}
else if (fk == -1)
{
perror("fork"); /* print an error message */
}
return 0;
}
void time()
{
struct tm data;
data.tm_year=2015-1900;
data.tm_mon=1-1;
data.tm_mday=03;
data.tm_hour=10;
data.tm_min=49;
data.tm_sec=10;
data.tm_isdst = -1;
if(mktime(&data) == time(NULL))
{
taskexecution();
}
}
int main ()
{
while(1)
{
time();
}
return 0;
}
Your problem is that the computer runs so fast that your time() function can be called several times in the same second. What you need is to ensure that either your function stops the while loop after having run the task, or forbids the execution of the task:
First:
int time()
{
struct tm data;
data.tm_year=2015-1900;
data.tm_mon=1-1;
data.tm_mday=03;
data.tm_hour=10;
data.tm_min=49;
data.tm_sec=10;
data.tm_isdst = -1;
if (mktime(&data) == time(NULL))
{
taskexecution();
return 0; // returns 0 to stop while
}
return 1; // returns 1 to let the while continue
}
int main ()
{
while(time());
return 0;
}
second:
void time()
{
static int ran = 0; // static variable: 0 is task not already executed, 1 else
struct tm data;
data.tm_year=2015-1900;
data.tm_mon=1-1;
data.tm_mday=03;
data.tm_hour=10;
data.tm_min=49;
data.tm_sec=10;
data.tm_isdst = -1;
if(ran==0 && mktime(&data) == time(NULL))
{
taskexecution();
ran = 1; // Ok execution took place
}
}
Related
I have program and I want it to create a thread, thread 'a', I want it to wait for input from a file to be read into a buffer, buffer 1, then execute its function and put the answer to that question in a second buffer, buffer 2. At the moment the thread waits but it never executes and I can't figure out why. Could it be that the parent thread is exiting before thread 'a' has a chance to execute? If this is the case how do I stop the parent thread from exiting? If it is not the case could I have some pointers on what I am doing wrong
The code is below.
EDIT: This is a homework assignment and it has to be done in this manner as opposed to reading in the input first or having the thread read the input.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include "LinkedList.h"
#include "macros.h"
#include "FileReading.h"
pthread_mutex_t lock;
pthread_cond_t cond;
int returnSeekTime(int curData, int nextData)
{
int seekTime;
if (curData > nextData)
{
seekTime = curData - nextData;
}
else
{
seekTime = nextData - curData;
}
return seekTime;
}
void* firstComeFirstServed(void* data)
{
Buffers* buffers = (Buffers*)data;
Buffer1 buffer1 = buffers->buffer1;
Buffer2 buffer2 = buffers->buffer2;
int curData, nextData;
Node* current = current = buffer1.disks->head;
pthread_cond_wait(&cond, &lock);
buffer2.seekTime += returnSeekTime(buffer1.secondDisk, current->data);
while(current != NULL && current != buffer1.disks->tail)
{
curData = current->data;
nextData = current->next->data;
buffer2.seekTime += returnSeekTime(curData, nextData);
current = current->next;
}
return NULL;
}
int main (void)
{
char fileName[11] = "input.txt\0";
pthread_t a;
Buffers* buffers = (Buffers*)malloc(sizeof(Buffers));
buffers->buffer1.disks = createLinkedList();
pthread_create(&a, NULL, firstComeFirstServed, (void*)buffers);
readInputFile(fileName, &buffers->buffer1);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&lock);
return 0;
}
Im trying to write a function that unlocks all pthread mutexes provided in an array of mutexes.
The array is mutexv and the number of mutexes in given by mutexc.
The function should return 0 on success,
-1 otherwise.
my function so far:
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <alloca.h>
#include "pthread.h"
#include "multi_mutex.h"
int multi_mutex_unlock(pthread_mutex_t **mutexv, int mutexc)
{
(void) mutexv;
(void) mutexc;
pthread_mutex_init(*mutexv, NULL);
for (int i=0; i<mutexc; i++){
if (pthread_mutex_unlock(*mutexv) !=0){
return -1;
}
}
return 0;
}
having a hard time figuring out what im doing wrong.
// correct type for specifying array sizes is size_t, not int:
int multi_mutex_unlock(pthread_mutex_t **mutexv, size_t mutexc)
{
// you wouldn't initialize here, that needs to occur much earlier
//pthread_mutex_init(*mutexv, NULL);
for (size_t i = 0; i < mutexc; i++)
{
if (pthread_mutex_unlock(mutexv[i]) != 0)
// you need to index properly ^^^
{
return -1;
}
}
return 0;
}
Actually a while loop can be more elegant:
int multi_mutex_unlock(pthread_mutex_t **mutexv, size_t mutexc)
{
while(mutexc)
{
if (pthread_mutex_unlock(*mutexv) != 0)
{
return -1;
}
mutexc--; // decrement the remaining number
mutexv++; // increment the pointer to point to next mutex
}
return 0;
// or totally compact as:
for(; mutexc; --mutexc, ++mutexv)
{
if (pthread_mutex_unlock(*mutexv) != 0)
{
return -1;
}
}
}
Finally: You don't give any information on how many mutexes actually could be unlocked (or alternatively, how many have not) – you might return that number instead of -1, then any value different from originally passed mutexc would mean an error occurred.
I'm developing a micro-game in c using the ncurses library for the front-end.
I simplified the code to the minimum, the expected result should be a shuttle that periodically shoots one bomb.
The problem is that when the program runs, the first shoot is always duplicated then sometimes the problem occurs again.
There are 2 processes that communicate through a pipe.
Here is a minimal version of the program to highlight the error:
#include <curses.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define ENEMYSPRITE "()"
#define BOMB "#"
typedef struct {
char * c;
int x;
int y;
int oldx;
int oldy;
}
pos;
void bombe(int pipeout, pos pos_enemy) {
pos pos_bomba;
pos_bomba.c = BOMB;
pos_bomba.x = pos_enemy.x;
pos_bomba.y = pos_enemy.y + 1;
write(pipeout, & pos_bomba, sizeof(pos_bomba));
while (1) {
pos_bomba.oldy = pos_bomba.y;
pos_bomba.oldx = pos_bomba.x;
pos_bomba.y++;
write(pipeout, & pos_bomba, sizeof(pos_bomba));
usleep(150000);
}
_exit(0);
}
void gameBoard(int pipein) {
pos pos_enemy, pos_bomba, readValue;
while (1) {
read(pipein, & readValue, sizeof(readValue));
if (strcmp(readValue.c, BOMB) == 0) {
mvaddstr(pos_bomba.oldy, pos_bomba.oldx, " "); // deleting the old bullet's position
pos_bomba = readValue;
}
mvaddstr(readValue.y, readValue.x, readValue.c);
refresh();
}
}
void enemy(int pipeout) {
pid_t pid_bomba;
pos pos_enemy;
pos_enemy.c = ENEMYSPRITE;
pos_enemy.x = 10;
pos_enemy.y = 5;
write(pipeout, & pos_enemy, sizeof(pos_enemy));
while (1) {
pid_bomba = fork();
if (pid_bomba == 0) {
bombe(pipeout, pos_enemy);
}
write(pipeout, & pos_enemy, sizeof(pos_enemy));
usleep(1000000);
}
}
int main(int argc, char ** argv) {
initscr();
noecho();
curs_set(0);
int fdescriptor[2];
pipe(fdescriptor);
pid_t pidEnemy = fork();
if (pidEnemy == 0) {
close(fdescriptor[0]);
enemy(fdescriptor[1]);
} else {
close(fdescriptor[1]);
gameBoard(fdescriptor[0]);
}
return 0;
}
I believe the problem with our code is inside function bombe(). Here is the revision that fixed the problem of initially it shoots twice.
void bombe(int pipeout, pos pos_enemy) {
pos pos_bomba = pos_enemy;
pos_bomba.c = BOMB;
pos_bomba.y = pos_enemy.y + 1;
while (1) {
pos_bomba.oldy = pos_bomba.y;
pos_bomba.oldx = pos_bomba.x;
write(pipeout, & pos_bomba, sizeof(pos_bomba));
++pos_bomba.y;
usleep(1155000);
}
_exit(0);
}
Note that now only one write() inside this function.
I have been learning how to use Unix functions to program in C so that I can program Semaphore functionality by scratch (without pthreads), but I am currently stuck. The man pages told me to include particular header files to use functions of interest (such as malloc, tsleep, wakeup, etc.), but when I try to run my program with the headers and method calls, I receive the following errors:
/tmp//ccg29960.o: In function `allocate_semaphore':
/tmp//ccg29960.o(.text+0x28d): undefined reference to `simple_lock_init'
/tmp//ccg29960.o: In function `down_semaphore':
/tmp//ccg29960.o(.text+0x2fb): undefined reference to `tsleep'
/tmp//ccg29960.o: In function `up_semaphore':
/tmp//ccg29960.o(.text+0x3b5): undefined reference to `wakeup'
/tmp//ccg29960.o: In function `free_semaphore':
/tmp//ccg29960.o(.text+0x43b): undefined reference to `simple_lock'
/tmp//ccg29960.o(.text+0x4af): undefined reference to `simple_unlock'
collect2: ld returned 1 exit status
The relevant code is below:
//#include <stdio.h>
//#include <stdlib.h>
#include <sys/errno.h>
#include <sys/queue.h>
//#include <sys/time.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/proc.h>
#include <sys/malloc.h>
#include <sys/lock.h>
struct entry
{
pid_t id;
SIMPLEQ_ENTRY(entry) next;
} *np;
typedef struct
{
const char* name;
pid_t process;
pid_t p_process; //parent process
int count;
SIMPLEQ_HEAD(queuehead,entry) head;
struct simplelock *slock;
} named_semaphore;
named_semaphore* s_list[64];
int num_semaphores = 0;
int main()
{
//lockinit(0, 0, 0,0, 0);
printf("Hello world\n");
return 0;
}
//... irrelevant code elided
int allocate_semaphore( const char* name, int initial_count )
{
int num_elements, i;
named_semaphore *new_s;
//perform initial checks before creating a new semaphore
//make sure the given name is an acceptable length
num_elements = sizeof(name) / sizeof(*name);
if ( num_elements > 32 )
{
return ENAMETOOLONG;
}
//make sure the given name is unique to this process
for (i = 0; i < num_semaphores; i++)
{
if (s_list[i]->process == getpid() && strcmp(s_list[i]->name, name))
{
return EEXIST;
}
}
//make sure there are no more than 64 semaphores active
if (num_semaphores >= 64)
{
return ENOMEM;
}
//create a new semaphore and add it to the collection
new_s = (named_semaphore*) malloc(sizeof(named_semaphore), 0, 0);
new_s->name = name;
new_s->process = getpid();
new_s->p_process = getppid();
new_s->count = initial_count;
s_list[num_semaphores] = new_s;
++num_semaphores;
//initialize the waiting queue
SIMPLEQ_INIT( &(new_s->head) );
//initialize its lock
simple_lock_init( new_s->slock );
//need to handle negative initial_count somehow
return (0);
}
int down_semaphore( const char* name )
{
named_semaphore* s;
s = getSemaphore( name );
if (s == NULL)
{
return (ENOENT);
}
s->count = (s->count) - 1;
if (s->count < 0)
{
//put process to sleep
tsleep(getpid(), getpriority(), 0, 0);
//add process to waiting queue
np = (struct entry *) malloc(sizeof(struct entry ));
np->id = getpid();
SIMPLEQ_INSERT_TAIL( &(s->head), np, next );
}
return 0;
}
int up_semaphore ( const char* name )
{
named_semaphore* s;
s = getSemaphore( name );
if ( s == NULL )
{
return (ENOENT);
}
s->count = (s->count) + 1;
if (s->count <= 0)
{
//wakeup longest waiting process
wakeup( (SIMPLEQ_FIRST( &(s->head) ))->id );
//remove process from waiting queue
SIMPLEQ_REMOVE_HEAD( &(s->head), np, next );
free( np );
}
return 0;
}
int free_semaphore( const char* name )
{
named_semaphore* s;
s = getSemaphore( name );
if ( s == NULL )
{
return (ENOENT);
}
simple_lock( s->slock );
while ( (np = SIMPLEQ_FIRST( &(s->head) ) ) != NULL )
{
//wakeup the process and return ECONNABORTED
//wakeup( getSemaphore( np->id ) );
SIMPLEQ_REMOVE_HEAD( &(s->head), np, next );
free( np );
}
free( s );
simple_unlock( s->slock );
}
I am not done modifying/fixing the logic of my overall program (for example, the lock()ing only happens in 1/3 of the intended methods), but it would be wonderful to understand why I am getting my current error so that I know how to fix similar ones in the future.
To me it seems like the methods do not recognize their header files or that I am missing a required piece of information so that the two can communicate.
To fix the errors, I've tried rearranging and commenting out the listed header files and also renaming the method calls in uppercase letters like they were presented in the header file documentation.
Any help or insight is appreciated, and thank you in advance!
The man pages you read... those were section 9, weren't they? Section 9 is for kernel programming. You can't call those functions unless your code is in the kernel.
i have an array of structures with fields of data and fields with pointers to functions.
what i'm doing now is cycling through array and calling each registered function.
what i need is for each of element in my structures array call registered function in a separate independent thread.
i can post an code example also if needed. sorry for my english :)
posting code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#define NTHREAD 3
struct server_t {
char *name;
int (*triggered)(struct server_t *);
};
typedef struct server_t server_t;
int triggered1(struct server_t * server)
{
if (time(NULL) % 1 == 0) {
printf("%s\n", __FUNCTION__);
pthread_exit(0);
return 0;
} else {
return -1;
}
}
int triggered2(struct server_t * server)
{
if (time(NULL) % 2 == 0) {
printf("%s\n", __FUNCTION__);
pthread_exit(0);
return 0;
} else {
return -1;
}
}
int triggered3(struct server_t * server)
{
if (time(NULL) % 5 == 0) {
printf("%s\n", __FUNCTION__);
pthread_exit(0);
return 0;
} else {
return -1;
}
}
int main()
{
pthread_t threads[NTHREAD];
int iret[NTHREAD]; int i = 0;
server_t servers[] = {
{"server1", triggered1},
{"server2", triggered2},
{"server3", triggered3},
};
/*
So, i have an array of structures. AND i have a main loop.
i want to create thread for each element of array, pass
structure's "triggered" function as start routine for it.
AND i need this start routine to periodically check for something.
So below some kind of an em.. code, that supposed to be.
*/
<create_threads(&servers);> // this function must create thread for each element of array
//with structure's "triggered" function as a start routine
//argument
/* after what threads are running and checking what they needed in an infinite loop. */
// ?maybe some code here?
return 0;
}
Here is a very good, basic pthreads example, which should get you going:
https://computing.llnl.gov/tutorials/pthreads/#CreatingThreads
Basically all you need to do is loop through your function-pointer-array and execute the functions according to the said example.