Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 28c5dfe

Browse files
author
Anton Yarkov
committed
Named and nonamed pipes examples.
1 parent ddce52c commit 28c5dfe

File tree

4 files changed

+286
-0
lines changed

4 files changed

+286
-0
lines changed

‎multithreading/03 - Nonamed_pipes.cpp

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
#include <iostream>
2+
#include <stdio.h>
3+
#include <stdlib.h>
4+
#include <unistd.h>
5+
#include <sys/types.h>
6+
#include <sys/wait.h>
7+
8+
using namespace std;
9+
10+
struct CmdLine
11+
{
12+
char* value;
13+
char* arguments;
14+
CmdLine* next;
15+
};
16+
17+
// Compilation:
18+
// g++ "03 - Nonamed_pipes.cpp" -o nonamedpipes
19+
20+
// Task:
21+
// Create a program which works just like the command below:
22+
// $> who | sort | uniq -c | sort -nk1
23+
24+
void run(CmdLine* command)
25+
{
26+
const int numPipes = 3;
27+
int i = 0;
28+
pid_t pid;
29+
30+
// Create all pipes.
31+
int pipefds[2*numPipes];
32+
for(i = 0; i < (numPipes); i++)
33+
{
34+
if(pipe(pipefds + i*2) < 0)
35+
{
36+
printf("Couldn't create pipe %d\n", i + 1);
37+
exit(EXIT_FAILURE);
38+
}
39+
}
40+
41+
int j = 0;
42+
while(command)
43+
{
44+
pid = fork();
45+
if(pid == 0)
46+
{
47+
//if not last command
48+
if(command->next)
49+
{
50+
if(dup2(pipefds[j + 1], STDOUT_FILENO) < 0)
51+
{
52+
perror("dup2");
53+
exit(EXIT_FAILURE);
54+
}
55+
}
56+
57+
//if not first command && j != 2*numPipes
58+
if(j != 0 )
59+
{
60+
if(dup2(pipefds[j-2], STDIN_FILENO) < 0)
61+
{
62+
perror(" dup2");///j-2 0 j+1 1
63+
exit(EXIT_FAILURE);
64+
}
65+
}
66+
67+
68+
for(i = 0; i < 2*numPipes; i++)
69+
{
70+
close(pipefds[i]);
71+
}
72+
73+
// Command with or without arguments.
74+
if (command->arguments == NULL)
75+
{
76+
if( execlp(command->value, command->value, NULL) < 0 )
77+
{
78+
perror(command->value);
79+
exit(EXIT_FAILURE);
80+
}
81+
}
82+
else
83+
{
84+
if( execlp(command->value, command->value, command->arguments, NULL) < 0 )
85+
{
86+
perror(command->value);
87+
exit(EXIT_FAILURE);
88+
}
89+
}
90+
}
91+
else if(pid < 0)
92+
{
93+
perror("error");
94+
exit(EXIT_FAILURE);
95+
}
96+
97+
command = command->next;
98+
j+=2;
99+
}
100+
101+
/* Parent closes the pipes and wait for children */
102+
for(i = 0; i < 2 * numPipes; i++)
103+
{
104+
close(pipefds[i]);
105+
}
106+
107+
int status;
108+
for(i = 0; i < numPipes + 1; i++)
109+
{
110+
wait(&status);
111+
}
112+
}
113+
114+
int main(int argc, char** argv)
115+
{
116+
printf("Result of operation is the same like if you type\n$>who | sort | uniq -c | sort -nk1\n");
117+
118+
char sort[] = "sort";
119+
char sortArg[] = "-nk1";
120+
char uniq[] = "uniq";
121+
char uniqArg[] = "-c";
122+
char who[] = "who";
123+
124+
CmdLine command4 = { sort, sortArg, NULL };
125+
CmdLine command3 = { uniq, uniqArg, &command4 };
126+
CmdLine command2 = { sort, NULL, &command3 };
127+
CmdLine command1 = { who, NULL, &command2 };
128+
129+
run(&command1);
130+
131+
return 0;
132+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
#include <unistd.h>
5+
#include <sys/types.h>
6+
7+
#define EXIT_FAILURE 1
8+
9+
// Compilation:
10+
// gcc "03 - Nonamed_pipes_read_write.c" -o nonamedpipesrw
11+
12+
// Task:
13+
// Do write on one end and read on another end.
14+
15+
void main()
16+
{
17+
int fd[2], nbytes;
18+
pid_t childpid;
19+
char string[] = "Hello, world!\n";
20+
char readbuffer[80];
21+
22+
pipe(fd);
23+
24+
printf("Process %d creates child\n", getpid());
25+
26+
if((childpid = fork()) == -1)
27+
{
28+
perror("fork");
29+
exit(EXIT_FAILURE);
30+
}
31+
32+
if(childpid == 0)
33+
{
34+
/* Child process closes up input side of pipe */
35+
close(fd[0]);
36+
37+
/* Send "string" through the output side of pipe */
38+
write(fd[1], string, (strlen(string)+1));
39+
printf("Done write in process %d\n", getpid());
40+
exit(0);
41+
}
42+
else
43+
{
44+
/* Parent process closes up output side of pipe */
45+
close(fd[1]);
46+
47+
/* Read in a string from the pipe */
48+
nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
49+
printf("Received string: %s in process %d\n", readbuffer, getpid());
50+
}
51+
52+
exit(0);
53+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#include <stdio.h>
2+
#include <unistd.h>
3+
4+
// Compilation:
5+
// gcc "03 - Nonamed_pipes_wc_logins.c" -o nonamedpipeslogins
6+
7+
// Task:
8+
// Create a program which works just like the command
9+
// $> who | wc -l
10+
11+
// Help:
12+
// Create pipe: who -> stdout -> [pfd[1] -> pfd[0]] -> stdin -> wc -l
13+
void main()
14+
{
15+
printf("Result of operation is the same like if you type\n$>who | wc -l\n");
16+
17+
int pfd[2];
18+
19+
pipe(pfd);
20+
21+
if (!fork())
22+
{
23+
// Since descriptors are shared between the parent and child,
24+
// we should always be sure to close the end of pipe we aren't concerned with.
25+
// On a technical note, the EOF will never be returned
26+
// if the unnecessary ends of the pipe are not explicitly closed.
27+
close(STDOUT_FILENO);
28+
dup2(pfd[1], STDOUT_FILENO);
29+
close(pfd[1]);
30+
close(pfd[0]);
31+
execlp("who", "who", NULL);
32+
}
33+
else
34+
{
35+
close(STDIN_FILENO);
36+
dup2(pfd[0], STDIN_FILENO);
37+
close(pfd[1]);
38+
close(pfd[0]);
39+
execlp("wc", "wc", "-l", NULL);
40+
}
41+
exit(0);
42+
}

‎multithreading/04 - Named_pipes.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#include <fcntl.h>
2+
#include <stdio.h>
3+
#include <stdlib.h>
4+
#include <string.h>
5+
#include <unistd.h>
6+
#include <sys/types.h>
7+
#include <sys/stat.h>
8+
9+
#define EXIT_FAILURE 1
10+
11+
// Compilation:
12+
// gcc "04 - Named_pipes.c" -o namedpipes
13+
14+
// Task:
15+
// Create Named Pipe aka FIFO to do write on one end and read on another end.
16+
17+
void main()
18+
{
19+
char * myfifo = "/tmp/myfifo";
20+
mkfifo(myfifo, 0666);
21+
22+
23+
pid_t childpid;
24+
if((childpid = fork()) == -1)
25+
{
26+
perror("fork");
27+
exit(EXIT_FAILURE);
28+
}
29+
30+
if(childpid == 0)
31+
{
32+
char string[] = "Hello, world!";
33+
int fd;
34+
if (fd = open(myfifo, O_WRONLY))
35+
{
36+
write(fd, string, (strlen(string)+1));
37+
close(fd);
38+
}
39+
40+
printf("Process %d done write and unlink fifo.\n", getpid());
41+
unlink(myfifo);
42+
}
43+
else
44+
{
45+
printf("Process %d creates child %d\n", getpid(), childpid);
46+
47+
char readbuffer[80];
48+
int fd;
49+
if (fd = open(myfifo, O_RDONLY))
50+
{
51+
read(fd, readbuffer, 80);
52+
printf("Process %d received string: %s\n", getpid(), readbuffer);
53+
close(fd);
54+
}
55+
unlink(myfifo);
56+
}
57+
58+
exit(0);
59+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /