Following on from my post here, I have found that sem_init is failing for me whenever I pass a negative value as the value parameter. However, when the sem_init below fails, the error number is set to 0, i.e. No Error. I hope the solution to this problem can assist in the solution to my other problem.
Note: I am using pthreads-win32 on MS Visual Studio 2015, and have no compilation errors or warnings.
Includes and semaphore declarations:
// pthread-win32 defines
#ifdef _WIN32
#define HAVE_STRUCT_TIMESPEC
#endif // _WIN32
// Includes
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <pthread.h>
#include <semaphore.h>
#include "include.h"
// Platform includes
#ifdef _WIN32
#include <fcntl.h>
#include <sched.h>
#include <windows.h>
#else
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#endif // _WIN32
// Globals
sem_t queue_semaphore;
sem_t test_mode_semaphore;
Code section:
if (sem_init(&test_mode_semaphore, 0, -2) == -1) {
perror("Error initialising semaphore"); // Error occurring here
}
for (int i = 0; i < 3; i++) {
/* Start Critical Region */
pthread_mutex_lock(&mutex_qq);
//...
// Increment value of queue_semaphore by 1
if (sem_post(&queue_semaphore) == -1) {
perror("Error incrementing semaphore");
}
/* End Critical Region */
pthread_mutex_unlock(&mutex_qq);
}
// Wait
if (sem_wait(&test_mode_semaphore)) {
perror("Error waiting for semaphore");
}
// Destroy test mode semaphore
sem_destroy(&test_mode_semaphore);
Related
I can't figure out what I missed. The first time that I run this msgget() retuns 0 but msgctl() can remove it. The second time still having 0 and msgctl() aborts with invalid argument error.
Already tried to use some key instead of IPC_PRIVATE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/msg.h>
#include <time.h>
#define DEBUG
int main(){
int queue_id;
if(queue_id = msgget(IPC_PRIVATE, IPC_CREAT | IPC_EXCL | 0600) == -1){
perror("queue");
return -1;
}
if(msgctl(queue_id, IPC_RMID, NULL) == -1) {
perror("queue rmid:");
}
return 0;
}
== binds more tightly than =. Try putting parentheses around the assignment of queue_id, or put it on its own line:
queue_id = msgget(IPC_PRIVATE, IPC_CREAT | IPC_EXCL | 0600);
if(queue_id == -1) {
perror("queue");
return -1;
}
Running your compiler with -Wall -Wextra -Werror will help with this kind of thing.
Can I use the kill() function to send a signal to another process? It should be possible, but kill() fails and I can't understand why.
I have two programs (process_1 and process_2). The first one should set a signal handler to increase a variable, than create a child that uses execve and loads process_2. The other program should send the signal using kill(). I used the shared memory to share process_1's pid through a struct (because I have other variables to share). The code of the first program is as follows:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <signal.h>
#include <errno.h>
#include <time.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/wait.h>
#define KEY_SM 1234
static int value_to_change=0;
typedef struct keys{
pid_t pid_process;
}keynote;
static void test_handler(int signo){
if(signo=SIGUSR1){
printf("received SIGUSR1\n");
value_to_change++;
}
}
int main(){
if((signal(SIGUSR1, test_handler))==SIG_ERR) perror("Errore allocazione SIGUSR1");
int flags = S_IRUSR|S_IWUSR|IPC_CREAT;
size_t shm_size = sizeof(keynote);
int shm_id = shmget(KEY_MC, shm_size, flags);
keynote *chv = shmat(shm_id, NULL, 0);
chv->pid_process=getpid();
printf("%d\n",chv->pid_process);
int process_2;
process_2=fork();
if(process_2==0){
char* argv[]={"process_1", "process_2", NULL};
if((execve("process_2", argv, NULL))<0) perror("execve error");
exit(0);
}else if(process_2<0)perror("fork error");
return 0;
}
The second program code is:
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <signal.h>
#include <errno.h>
#include <time.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <sys/wait.h>
#define KEY_SM 1234
typedef struct keys{
pid_t pid_process;
}keynote;
static void signal_to_send(pid_t process){
int ret=kill(process, SIGUSR1);
printf("%d", ret);
}
}
int main(int argc, char **argv){
int pid_of_process_1;
int flags = S_IRUSR|S_IWUSR|IPC_CREAT;
size_t shm_size = sizeof(keynote);
int shm_id = shmget(KEY_MC, shm_size, flags);
keynote *chv = shmat(shm_id, NULL, 0);
signal_to_send(chv->pid_process);
return 0;
}
process_1 does not wait for process_2. It just exits immediately. At which point process_2 may not even have started. So when process_2 sends the signal, process_1 is likely to not exist anymore.
– kaylum
Following code I have done so far. It creates the file but permission access in its properties is no read and write. Thus, when I enable it and run the program again and input the same file name. It works very well.
So the question is, how do I give access to the file to be read and write in the code?
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/file.h>
#define BLOCK_SIZE 4096
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/file.h>
#define BLOCK_SIZE 4096
int main()
{
int readfile=-1,openfile=-1, size=0, i=0;
char str[100],fname[50],new_fname[50];
printf("Enter name of file to copy: ");
scanf("%s",fname);
printf("Enter name of new file:");
scanf("%s",new_fname);
readfile=open(fname,O_CREAT|O_APPEND|O_RDONLY);
if(readfile == -1)
{
printf("Open Failed");
return 1;
}
else
{
size=read(readfile,str,BLOCK_SIZE);
openfile=open(new_fname,O_CREAT|O_WRONLY|O_EXCL);
write(openfile,str,size);
flock(openfile,LOCK_UN);
}
close(openfile);
close(readfile);
return 0;
}
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 code, which throws the error
Virtual time expired.
Shouldn't the program run in an infinite loop?
#define KTHREAD_VTALRM_SEC 0
#define KTHREAD_VTALRM_USEC 100000
#include <stdio.h>
#include <unistd.h>
#include <linux/unistd.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sched.h>
#include <signal.h>
#include <setjmp.h>
#include <errno.h>
#include <assert.h>
#include <string.h>
#include <time.h>
int main()
{
struct itimerval timeslice;
timeslice.it_interval.tv_sec = KTHREAD_VTALRM_SEC;
timeslice.it_interval.tv_usec = KTHREAD_VTALRM_USEC;
timeslice.it_value.tv_sec = KTHREAD_VTALRM_SEC;
timeslice.it_value.tv_usec = KTHREAD_VTALRM_USEC;
setitimer(ITIMER_VIRTUAL,×lice,NULL);
while(1)
{
;
}
}
When the timer expires it will deliver a SIGVTALRM signal, which you are not handling.
See the man pages for setitimer() and signal().
You did not set a signal handler.
The default handler for VTALRM signal is "exit" (ref: http://manpages.ubuntu.com/manpages//precise/en/man1/kill.1.html.)
So if you want to replace the default behavior with yours, you have to define a new signal handler and register it:
void vtHandler(int sig)
{
// Do something here
}
int main()
{
// Register timer handler
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = timer_handler;
if (sigaction(SIGVTALRM, &sa, NULL) == -1)
//error handle
;
}
PS: If you utilize signal method, sure that it is well implemented on your system (ref: http://manpages.ubuntu.com/manpages//precise/en/man2/signal.2.html)