I am trying to make my aperiodic task wait for a specific key press event.My
aperiodic function waits first time for the event to occur but post that it runs 3 iterations without waiting and then waits again. I am unable to discern mistake in the code. I have initialized the array of event semaphores with value 0 for each
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <linux/input.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
sem_t mutex[10],event[10];
sem_t mtx,mtx1,mtx2,mtx3; //These 4 mutexes and the array mutex[10] are defined for periodic task
typedef struct task
{
int taskid;
int priority;
int iter;
}task;
void *wait_for_event()
{
int fd;
fd = open("/dev/input/by-path/platform-i8042-serio-0-event-kbd", O_RDONLY);
struct input_event ev;
while (1)
{
read(fd, &ev, sizeof(struct input_event));
if(ev.type == 1) /* signal any waiting thread for keypress event */
sem_post(&event[(ev.code -1)%10]);
}
}
void *aperiodic(void *t)
{
pthread_t tid;
sem_wait(&mtx);
while(1){
sem_wait(&mtx1);
int i,j;
struct task *temp=(struct task *)t;
printf(" The running task is : %d",temp->taskid);
/*do some busy computation */
for(i=0;i<temp->iter;i++)
{
j=i+j;
}
printf("\nTOTAL iterations %d\n", j);
printf("\n ENTERED APERIODIC TASK..Enter the input event id\n");
/*wait for event with the task id temp->taskid to occur. This sem_wait waits for keypress event. But it is not waiting in every iteration of while loop. It is waiting once in 3 iterations. */
sem_wait(&event[temp->taskid]);
sem_post(&mtx1);
}
in main method i have initialized
for(i=1;i<=10;i++)
{ /*the initial value of all mutexes in event array is 0 */
sem_init(&event[i],0,0);
}
Related
I'm trying to write multithread program to calculate usage of processor. The problem is that i don't know how to safely end threads. I have to end them by signal SIGTERM and I tried
while(flag), phread_exit(), exit(), return(void*)0 but non of them work. I need to end infinite loop and return to main function. I've got two results: Exiting the whole program or program stopped and do nothing.
How can I solve it?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <signal.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/sysinfo.h>
#include <ctype.h>
#include <malloc.h>
#include <time.h>
#include <semaphore.h>
#include "cpudata.h"
#include"cpu_result.h"
#include "reader.h"
#include "analyzer.h"
#include "writer.h"
#define NUM_THREADS 3 //Number of threads
//Declaring variables as volatile
volatile struct cpu_data *datax1;
volatile struct cpu_data *datax2;
volatile struct cpu_result *result;
//Declaring semaphores
sem_t sem1;
sem_t sem2;
sem_t sem3;
volatile int flag=1;
volatile int val[NUM_THREADS]={0,0,0};
void handle_sigterm(int signum)
{
flag=0;
}
void *reader(void *ptr) //Thread to read
{ while(flag){
sem_post(&sem3);
sem_wait(&sem1);
sleep(1); //Make sure that semaphores changes value
load_data(datax1);
sleep(1); //Making sure that values datax1 and datax2 are different
load_data(datax2);
if(datax1==datax2) //checking if values are different
{
perror("Datas are the same \n");
}
}
pthread_exit(val[0]);
}
void *analyzer(void *ptr)//Thread to calculate data
{ while(flag){
sem_post(&sem1);
sem_wait(&sem2);
sleep(1);//Make sure that semaphores changes value
for(int i=0;i<NOPT+1;i++)
{
result[i]=calculate(datax1[i],datax2[i]);//calculating data
}
}
pthread_exit(val[1]);
}
void *writer(void *ptr)//thread to write data
{ while(flag){
sem_post(&sem2);
sem_wait(&sem3);
sleep(1);//Make sure that semaphores changes value
writeresult(result);
printf("\n\n\n\n\n\n");
}
pthread_exit(val[2]);
}
int main(int argc, char **argv)
{
struct sigaction action;
memset(&action,0,sizeof(struct sigaction));
action.sa_handler=handle_sigterm;
sigaction(SIGTERM,&action,NULL);
//Allocating memory for data
datax1=(struct cpu_data *)malloc((NOPT+1)*sizeof(struct cpu_data));
datax2=(struct cpu_data *)malloc((NOPT+1)*sizeof(struct cpu_data));
result=(struct cpu_result *)malloc((NOPT+1)*sizeof(struct cpu_result));
pthread_t thread[NUM_THREADS];//declaring threads
//Initializing semaphores
sem_init(&sem1,0,1);
sem_init(&sem2,0,1);
sem_init(&sem3,0,1);
//creating threads
pthread_create(&thread[0],NULL, &reader, NULL);
pthread_create(&thread[1],NULL, &analyzer, NULL);
pthread_create(&thread[2],NULL, &writer, NULL);
//make sure threads are working
for(int i=0;i<NUM_THREADS;i++){
pthread_join(thread[0],NULL);
pthread_join(thread[1],NULL);
pthread_join(thread[2],NULL);
}
//stopping threads
for(int i=0;i<NUM_THREADS;i++){
pthread_cancel(thread[0]);
pthread_cancel(thread[1]);
pthread_cancel(thread[2]);
}
//freeing memory
sem_destroy(&sem1);
sem_destroy(&sem2);
sem_destroy(&sem3);
free(datax1);
free(datax2);
free(result);
printf("SAFETY CLOSING");
return 0;
}
I'm trying to implement the producer/consumer problem in C. I know how to handle it with "fork", but in this case I shall implement two programs. One for producer and one for consumer.
For producer: a semaphore has to be initialized and in a loop (to 100), the semaphore shall increment its value and print it. This already works fine.
For consumer: the semaphore initialized in producer, shall be opened and in a loop (to 10) its value shall be decremented and printed.
When I run the process for consumer: a memory-access error is printed.
I have absolutely no idea, what I'm doing wrong. Thanks for any help!
consumer:
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/stat.h>
int main() {
int value;
sem_t *mySem = sem_open("sem", O_CREAT|O_EXCL , S_IRUSR|S_IWUSR , 0);
for(int i=0; i < 10; i++) {
sem_wait(mySem);
sem_getvalue(mySem, &value);
printf("The value of the semaphore is %d\n", value);
}
sem_close(mySem);
sem_unlink("sem");
return 0;
}
producer:
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
sem_t sem;
int main() {
sem_init(&sem, 0, 0);
int value;
for(int i=0; i < 100; i++) {
sleep(1);
sem_post(&sem);
sem_getvalue(&sem, &value);
printf("The value of the semaphore is %d\n", value);
}
sem_destroy(&sem);
return 0;
}
Hmm, what do you expect sem_init(&sem, 0, 0); to do? What relationship does that sem have with the consumer?
For two unrelated processes to communicate over anyn IPC, they have to agree on a resource by name. That's true if they share a file. It's also true if they share a semaphore. That's what named semaphores are for.
I modified your programs to use one named semaphore. The producer creates it and owns it exclusively; the consumer errors out if it's not there.
Consumer:
#include <err.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/stat.h>
#include <sys/types.h>
static const char name[] = "sem";
int main() {
int value;
sem_t *sem = sem_open(name, 0, S_IRUSR|S_IWUSR, 0);
if( sem == SEM_FAILED ) {
err(EXIT_FAILURE, "sem_open");
}
for(int i=0; i < 10; i++) {
sem_wait(sem);
sem_getvalue(sem, &value);
printf("The value of the semaphore is %d\n", value);
}
if( -1 == sem_close(sem) ) {
err(EXIT_FAILURE, "sem_close");
}
if( -1 == sem_unlink(name) ) {
err(EXIT_FAILURE, "sem_unlink");
}
return 0;
}
Producer:
#include <err.h>
#include <fcntl.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static const char name[] = "sem";
int main() {
sem_unlink(name); // ignore error if not extant
int value;
sem_t *sem = sem_open(name, O_CREAT|O_EXCL, S_IRUSR|S_IWUSR, 0);
if( sem == SEM_FAILED ) {
err(EXIT_FAILURE, "sem_open");
}
for(int i=0; i < 100; i++) {
sleep(1);
sem_post(sem);
sem_getvalue(sem, &value);
printf("The value of the semaphore is %d\n", value);
}
sem_destroy(sem);
return 0;
}
I think you'll find they work better now. I recommend you follow my lead, though, and check every return code, and exit on error whenever anything goes wrong. For trial code like this, that's the quickest way to get it running correctly.
Thanks for correction. This works perfectly for my purpose.
With sem_init I supposed to initialize the semaphore with 0 as Start-Value.
Seems like the error was using this instead of a pointer and sem_open in the producer-process.
This was my first experience with named semaphores, so it was not easy to see my error.
Thank you very much
I have a program that prepares some configurations in one process and after that reads those configurations in the parent process. To sync them I'm using semaphores from semaphore.h library. But it seems that it's waiting forever in sem_wait even after I sem_post. It works after I do ctrl-z and fg though. Why is that? Can anyone tell me what's wrong with my code?
My OS is Lubuntu
Semaphore1.h
#ifndef _DNSS_H_
#define _DNSS_H_
#include <pthread.h>
#include <semaphore.h>
#include <time.h>
#include <sys/types.h>
typedef struct configs
{
int i;
sem_t sem;
} CONFIGS;
void init_config(CONFIGS *_configs);
//initiates the threadpool
int init_thread_pool(CONFIGS *configs);
#endif
Semaphore_1.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <semaphore.h>
#include <pthread.h>
#include "semaphore1.h"
void init_config(CONFIGS *_configs)
{
sem_init(&(_configs->sem),1,0); //Creaates a semaphore that is opened when the configs are read to shared memory
_configs->i=2;
fprintf(stderr, "Result of sem_post:%d\n", sem_post(&(_configs->sem)));
}
Semaphore_2.c
#include"semaphore1.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int init_thread_pool( CONFIGS *configs)
{
int aux;
fprintf(stderr, "Value of sem_wait():%d\n", sem_wait(&(configs->sem)));
printf("Threadpool initiated with %d threads!", configs->i);
return 1;
}
Semaphore_main.c
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include "semaphore1.h"
#include <sys/ipc.h>
#include <sys/shm.h>
int main(int argc, char *argv[])
{
pid_t config_pid; //will hold the configuration process id
int _shmid_configs;
CONFIGS *_configs;
_shmid_configs =shmget( IPC_PRIVATE,
sizeof(CONFIGS), IPC_CREAT|0666); //initializes the shared memory
if( _shmid_configs == -1)
{
perror("Error creating shared memory");
}
_configs=shmat(_shmid_configs, NULL,0); //maps the shared memory created to the processp and the config structure
if( _configs == ( CONFIGS*)-1)
{
perror("Error at shmat");
}
//initialization of the processes
config_pid = fork();
if( config_pid < 0)
{
perror("Failed creating configuration manager process");
}
else if( config_pid == 0)
{
init_config(_configs);
printf("Im config!\n");
return 0;
}
//CODE FOR THE gestor de pedidos
printf("right before the threadpool! Configs has a lmit of %d theads\n", _configs->i);
init_thread_pool(_configs);
printf("im parent and im out\n");
sem_destroy(&_configs->sem);
return 0;
}
Compiled with
gcc -g -pthread Semaphore_2.c Semaphore_main.c Semaphore_1.c -o deb
Output:
./deb
right before the threadpool! Configs has a lmit of 0 theads
Result of sem_post:0
Im config!
^Z
[1]+ Stopped ./deb
fg
./deb
Value of sem_wait():0
Threadpool initiated with 2 threads!im parent and im out
sem_init() should be called before fork().
In your current code it is possible for init_thread_pool(_configs); in the parent thread to be called before init_config(), that is you will wait on uninitialized semaphore. It is undefined behaviour.
I have the following libev code:
#include <ev.h>
#include <stdio.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <string.h>
#include <stdlib.h>
#include <sys/un.h>
#include <netinet/in.h>
ev_io stdin_watcher;
static void cb(EV_P_ ev_io *w, int revents){
puts ("hello");
//read file here - suggestion due to Ioan
#define BUF_LEN 10
char buf[BUF_LEN];
memset(buf,0,BUF_LEN);
int byte_read;
while( (byte_read = recv(w->fd,buf,BUF_LEN-1,0)) > 0) {
printf("len: %i: %s",byte_read,buf);
memset(buf,0,BUF_LEN);
}
if(-1 == byte_read && EAGAIN != errno) {
perror("recv");
}
close(w->fd);
//ev_io_stop (EV_A_ w);
//ev_unloop (EV_A_ EVUNLOOP_ALL);
}
int main (void){
struct ev_loop *loop = ev_default_loop (0);
int len;
int sd;
sd=socket(AF_UNIX,SOCK_STREAM,0);
struct sockaddr_un address;
//memset(&address,0,sizeof(address));
address.sun_family=AF_UNIX;
strcpy(address.sun_path,"/tmp/mysocket");
unlink(address.sun_path);
len=strlen(address.sun_path)+sizeof(address.sun_family);
int x=bind(sd,(struct sockaddr*)&address,sizeof(address));
printf("%d\n",x);
listen(sd,5);
ev_io_init(&stdin_watcher,cb,sd,EV_READ);
ev_io_start(loop,&stdin_watcher);
ev_loop (loop, 0);
// unloop was called, so exit
return 0;
}
Everything works just fine (almost). Compile: gcc file.c -lev, and run ./a.out. Then write to the socket that ./a.out is listening on: echo "gobblydeegook" | nc -U /tmp/mysocket.
Hello appears on the console as expected.
But the program calls the event and then it keeps printing "hello" ad-infinitum! I want it to continue monitoring this unix socket for writes. How to do this?
The event gets called when there is data to be read on the socket. Since you aren't removing the data from the socket, just printing "hello", the event is called again for you to handle the data.
I've written a program which forks in a loop. The only thing children processes do is to increase a counter and exit, whereas a parent process waits for each of them.
My goal is to measure user and system time of parent process and all his children separately.
I've succeded with parent process using times() function and struct tms. Surprisingly, the same aproach to children processes isn't working. What is the mistake that I'm doing? How to measure those times?
I've also tried getrusage() and I/it failed.
My code:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/times.h>
#include <time.h>
#ifndef COUNT
#define COUNT 100000
#endif
int counter;
int main(){
struct tms time1,time2;
times(&time1);
int count = COUNT;
pid_t pid;
while(count--){
if((pid=fork())<0){
printf("fork error\n");
} else if(pid==0){ /* child */
counter++;
_exit(0);
} else {
waitpid(pid,NULL,0); /*wait()*/
}
}
printf("COUNTER: %d\n",counter);
times(&time2);
long double clktck=sysconf(_SC_CLK_TCK);
double user=(time2.tms_utime-time1.tms_utime)/(double)clktck;
double system=(time2.tms_stime-time1.tms_stime)/(double)clktck;
double cuser=(time2.tms_cutime-time1.tms_cutime)/(double)clktck;
double csystem=(time2.tms_cstime-time1.tms_cstime)/(double)clktck;
printf("USER:%lf\nSYSTEM:%lf\n",user,system);
printf("CUSER:%lf\nCSYSTEM:%lf\n",cuser,csystem);
return 0;
}
I think the problem is that your children are executing too quickly; they don't take enough time to execute, so the sum of their time is plenty of zeros. To test this theory, I slightly changed your program:
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/times.h>
#include <time.h>
#ifndef COUNT
#define COUNT 100
#endif
int counter;
int main(){
struct tms time1,time2;
times(&time1);
int count = COUNT;
pid_t pid;
while(count--){
if((pid=fork())<0){
printf("fork error\n");
} else if(pid==0){ /* child */
int i;
for (i=0; i<10000; i++) {
printf("in child %i\n", getpid());
}
exit(0);
} else {
waitpid(pid,NULL,0); /*wait()*/
}
}
printf("COUNTER: %d\n",counter);
times(&time2);
printf("%lu %lu %lu %lu\n", time2.tms_utime, time2.tms_stime, time2.tms_cutime, time2.tms_cstime);
long double clktck=sysconf(_SC_CLK_TCK);
double user=(time2.tms_utime-time1.tms_utime)/(double)clktck;
double system=(time2.tms_stime-time1.tms_stime)/(double)clktck;
double cuser=(time2.tms_cutime-time1.tms_cutime)/(double)clktck;
double csystem=(time2.tms_cstime-time1.tms_cstime)/(double)clktck;
printf("USER:%lf\nSYSTEM:%lf\n",user,system);
printf("CUSER:%lf\nCSYSTEM:%lf\n",cuser,csystem);
return 0;
}
You'll see that I drastically cut down on the number of children, and made the children do some real work; 10_000 printf(... getpid()) operations. Now the times amount to something:
$ time ./times
...
in child 16181
COUNTER: 0
1 0 24 95
USER:0.010000
SYSTEM:0.000000
CUSER:0.240000
CSYSTEM:0.950000
real 0m2.234s
user 0m0.250s
sys 0m0.950s
I'm afraid your children just didn't have enough work to do to amount to anything. (Odd, sounds like parenting advice.)
Each child is given their own address space. The code will not work because it will increment it's own local copy of counter and quit, leaving the version in the parent process/all other children untouched.
Also, you are very likely to get some errors with that many children.
Sorry I could only help with half the program :(.