My question is, how can I pass the X value between process, I don't wanna use a global variable for this.
int main(int argc, char *argv[])
{
pid_t pid;
int x;
x = 1;
pid=fork();
// Daqui para baixo executa o fork
if (pid == 0){ //Processo filho
printf("Processo Filho\n");
x = x 2;
printf("Somando 2 ao X, temos: %d\n", x);
exit(0);
}
else
{ //Processo pai
printf("Processo pai\n");
printf("O valor inicial de X é: %d\n", x);
wait(NULL);
x = x * 4;
printf("Agora multiplicando o valor de X por 4 temos: %d\n", x);
printf("Criança completa\n");
}
return 0;
}
I'm trying just to print the X value using the shmget, but I get -1, I'm currently just testing if I can pass the X value using that
int main(int argc, char *argv[])
{
pid_t pid;
int x;
int shmid;
int *shmptr;
x = 1;
shmid = shmget(x, 4*sizeof(int), IPC_CREAT | 0666);
shmptr = (int *) shmat(shmid, NULL, 0);
pid=fork();
// Daqui para baixo executa o fork
if (pid == 0){ //Processo filho
printf("Processo Filho\n");
printf("%d\n",shmid);
x = x 2;
printf("Somando 2 ao X, temos: %d\n", x);
exit(0);
}
else
{ //Processo pai
printf("Processo pai\n");
printf("O valor inicial de X é: %d\n", x);
wait(NULL);
x = x * 4;
printf("Agora multiplicando o valor de X por 4 temos: %d\n", x);
printf("Criança completa\n");
}
return 0;
}
CodePudding user response:
When you fork, you are creating a process that is an exact copy of the current process. It also copies data so you have access to the exact same things you have on the main process except the pid (the return of the call to fork()).
So your x value is copied. If you change it in the child process it will not be changed in the parent process even if you are using global variables
int x = 0;
pid = fork();
if (pid == 0) // Child process
{
printf("%d\n", x); // will print 0
x ;
}
else
{
printf("%d\n", x); // Will print 0
}
printf("%d\n", x); // Will print 0 in the parent process and 1 in the child process
If you want to retrieve your X value from the child process you should look to the waitpid function.
Here is an example on how to use it:
int pid = fork();
if (pid == -1)
exit(1);
if (pid == 0) // Child
{
exit(42);
}
int wstatus;
if (waitpid(pid, &wstatus, 0) == -1)
exit(1);
if (!WIFEXITED(wstatus))
exit(1);
printf("process exit status: %d\n", WEXITSTATUS(wstatus)); // 42
CodePudding user response:
On POSIX systems it's also possible to use real-time signals to send up to 64 bits of data between processes. Per POSIX 7 2.4.2 Realtime Signal Generation and Delivery:
This section describes functionality to support realtime signal generation and delivery.
Some signal-generating functions, such as high-resolution timer expiration, asynchronous I/O completion, interprocess message arrival, and the
sigqueue()
function, support the specification of an application-defined value, either explicitly as a parameter to the function or in asigevent
structure parameter. The sigevent structure is defined in<signal.h>
and contains at least the following members:Member Type Member Name Description int sigev_notify Notification type. int sigev_signo Signal number. union sigval sigev_value Signal value. void(*)(union sigval) sigev_notify_function Notification function. (pthread_attr_t*) sigev_notify_attributes Notification attributes.
...
The
sigval
union is defined in<signal.h>
and contains at least the following members:Member Type Member Name Description int sival_int Integer signal value. void* sival_ptr Pointer signal value.
The
sival_int
member shall be used when the application-defined value is of type int; thesival_ptr
member shall be used when the application-defined value is a pointer.
Sending the value is simple:
int value = ...;
union sigval sv;
memset( &sv, 0, sizeof( sv ) );
sv.sival_int = value;
int rc = sigqueue( pid, SIGRTMAX, sv );
On a system with 64-bit pointers, you can hack the use of the sival_ptr
pointer field to send 64 bits of data:
uint64_t value = ...;
union sigval sv;
memset( &sv, 0, sizeof( sv ) );
sv.sival_ptr = ( void * )( uintptr_t ) value;
int rc = sigqueue( pid, SIGRTMAX, sv );
You can use a signal handler to retrieve the value:
void handler( int sig, siginfo_t *info, void *context )
{
int value = info->si_value.sival_int;
...
}
...
struct sigaction sa;
memset( &sa, 0, sizeof( sa ) );
sa.sa_sigaction = handler;
sa.sa_flags = SA_RESTART | SA_SIGINFO;
sigaction( SIGCHLD, &sa, NULL );
Or, using sigwaitinfo()
:
sigset_t sigSet;
memset( &sigSet, 0, sizeof( sigSet ) );
sigemptyset( &sigSet );
sigaddset( &sigSet, SIGRTMAX );
sigprocmask( SIG_BLOCK, &sigSet, NULL );
siginfo_t siginfo;
int sigNum = sigwaitinfo( &sigSet, &siginfo, );
if ( SIGRTMAX == sigNum )
{
int value = siginfo.si_value.sival_int;
...
}