没有影响
thread 1 | thread 2 |
---|---|
P(s) | P(s) |
P(t) | P(t) |
V(s) | V(s) |
V(t) | V(t) |
+
|
|
+ +--------------------+
V(t)| | |
| | |
+ | unsafe region t |
| | |
| | |
+ +---------+---------+ |
V(s)| | | | |
| | | | |
+ | | | |
| | | | |
| | | | |
+ | +---------+----------+
P(t)| | |
| | unsafe region s |
+ | |
| | |
| | |
+ +-------------------+
P(s)|
|
+
|
|
+----+----+----+----+----+----+----+----+----+ thread 1
P(s) P(t) V(s) V(t)
thread 1 | thread 2 |
---|---|
P(s) | P(s) |
P(t) | P(t) |
V(s) | V(t) |
V(t) | V(s) |
+
|
|
+ +-------------------+
V(s)| | |
| | |
+ | |
| | |
| | |
+ | +---------+----------+
V(t)| | | | |
| | | | unsafe |
+ | | | region |
| | | | t |
| | | | |
+ | +---------+----------+
P(t)| | |
| | |
+ | unsafe region s |
| | |
| | |
+ +-------------------+
P(s)|
|
+
|
|
+----+----+----+----+----+----+----+----+----+ thread 1
P(s) P(t) V(s) V(t)
thread 1 | thread 2 |
---|---|
P(s) | P(s) |
P(t) | P(t) |
V(t) | V(s) |
V(s) | V(t) |
+
|
|
+ +---------+
V(t)| | unsafe |
| | region |
+ | t |
| | |
| | |
+ +---------+---------+----------+
V(s)| | | | |
| | | | |
+ | | | |
| | | | |
| | | | |
+ | +---------+ |
P(t)| | |
| | |
+ | unsafe region s |
| | |
| | |
+ +------------------------------+
P(s)|
|
+
|
|
+----+----+----+----+----+----+----+----+----+ thread 1
P(s) P(t) V(t) V(s)
thread 1 | thread 2 |
---|---|
P(s) | P(s) |
P(t) | P(t) |
V(t) | V(t) |
V(s) | V(s) |
+
|
|
+ +------------------------------+
V(s)| | |
| | |
+ | |
| | |
| | |
+ | +----------+ |
V(t)| | | unsafe | |
| | | region | |
+ | | t | |
| | | | |
| | | | |
+ | +----------+ |
P(t)| | |
| | |
+ | unsafe region s |
| | |
| | |
+ +------------------------------+
P(s)|
|
+
|
|
+----+----+----+----+----+----+----+----+----+ thread 1
P(s) P(t) V(t) V(s)
不会死锁
如下图所示:
+
|
|
+ +----------+
V(c)| | |
| | |
+ | |
| | |
| | |
+ +----------+ | |
V(b)| | | | |
| | | | |
+ | | | |
| | | | |
| | | | |
+ +----------+ | |
P(b)| | |
| | |
+ | |
| | |
| | |
+ +----------+
P(c)|
|
+
|
|
+----+----+----+----+----+----+----+----+----+ thread 1
P(b) V(b) P(c) V(c)
thread | pairs of mutexes |
---|---|
1 | a&b a&c |
2 | b&c |
3 | a&b |
#include
#include "csapp.h"
sigjmp_buf buf;
void sigchild_handler(int sig) {
siglongjmp(buf, 1);
}
char *tfgets(char *s, int size, FILE *stream) {
if (Fork() == 0) {
Sleep(5);
exit(0);
}
switch (sigsetjmp(buf, 1)) {
case 0:
Signal(SIGCHLD, sigchild_handler);
return fgets(s, size, stream);
case 1:
return NULL;
}
}
int main(int argc, char* argv[]) {
char buf[MAXLINE];
if (tfgets(buf, MAXLINE, stdin) == NULL)
printf("BOOM!\n");
else
printf("%s", buf);
return 0;
}
#include
#include "csapp.h"
char *tfgets(char *s, int size, FILE *stream) {
fd_set read_set;
FD_ZERO(&read_set);
FD_SET(STDIN_FILENO, &read_set);
struct timeval timeout;
timeout.tv_sec = 5;
timeout.tv_usec = 0;
Select(1, &read_set, NULL, NULL, &timeout);
if (FD_ISSET(STDIN_FILENO, &read_set))
return fgets(s, size, stream);
else
return NULL;
}
int main(int argc, char* argv[]) {
char buf[MAXLINE];
if (tfgets(buf, MAXLINE, stdin) == NULL)
printf("BOOM!\n");
else
printf("%s", buf);
return 0;
}
#include
#include "csapp.h"
struct pack {
char *s;
int size;
FILE *stream;
};
char *ptr = NULL;
int timeout = -1;
void *thread_read(void *vargp) {
struct pack p = *(struct pack *)vargp;
ptr = fgets(p.s, p.size, p.stream);
timeout = 0;
}
void *thread_sleep(void *vargp) {
Sleep(5);
timeout = 1;
}
char *tfgets(char *s, int size, FILE *stream) {
pthread_t tid_read;
pthread_t tid_sleep;
struct pack p;
p.s = s;
p.size = size;
p.stream = stream;
Pthread_create(&tid_read, NULL, thread_read, (void*)&p);
Pthread_create(&tid_sleep, NULL, thread_sleep, NULL);
// wait 2 thread race result
while(timeout == -1) {}
if (timeout == 1) {
Pthread_cancel(tid_read);
return NULL;
} else {
Pthread_cancel(tid_sleep);
return ptr;
}
}
int main(int argc, char* argv[]) {
char buf[MAXLINE];
if (tfgets(buf, MAXLINE, stdin) == NULL)
printf("BOOM!\n");
else
printf("%s", buf);
return 0;
}
#include
#include "csapp.h"
#include "12.34.h"
int M1[N][M];
int M2[N][M];
int MUL12[N][M];
void *thread_mul(void *vargp) {
int idx = *(int*)vargp;
int start = ROWS_PER_THREAD * idx;
int i, j, k;
for (i = start; i < start+ROWS_PER_THREAD; i++)
for (j = 0; j < N; j++) {
int sum = 0;
for (k = 0; k < M; k++) {
sum += M1[i][k] * M2[k][j];
}
MUL12[i][j] = sum;
}
}
void concurrent_mul(void) {
pthread_t tid[THREAD];
int param[THREAD];
int i;
for (i = 0; i < THREAD; i++) {
param[i] = i;
Pthread_create(&tid[i], NULL, thread_mul, ¶m[i]);
}
for (i = 0; i < THREAD; i++) {
Pthread_join(tid[i], NULL);
}
}
int main(int argc, char* argv[]) {
concurrent_mul();
return 0;
}
更改:
@@ -1,6 +1,8 @@
/*
- * tiny.c - A simple, iterative HTTP/1.0 Web server that uses the
+ * 12.35.c - A simple, iterative HTTP/1.0 Web server that uses the
* GET method to serve static and dynamic content.
+ *
+ * concurrent server in multi process way.
*/
#include "csapp.h"
@@ -35,8 +37,14 @@
Getnameinfo((SA *) &clientaddr, clientlen, hostname, MAXLINE,
port, MAXLINE, 0);
printf("Accepted connection from (%s, %s)\n", hostname, port);
- doit(connfd); //line:netp:tiny:doit
- Close(connfd); //line:netp:tiny:close
+
+ if (Fork() == 0) {
+ Close(listenfd);
+ doit(connfd); //line:netp:tiny:doit
+ Close(connfd); //line:netp:tiny:close
+ exit(0);
+ }
+ Close(connfd);
}
}
проверьте разделы 11.6 и 12.2.1, объедините части кода вместе
太麻烦,不写了。
更改:
@@ -13,9 +13,13 @@
void clienterror(int fd, char *cause, char *errnum,
char *shortmsg, char *longmsg);
+void *thread(void *vargp);
+
int main(int argc, char **argv)
{
int listenfd, connfd;
+ int *connfdp;
+ pthread_t tid;
char hostname[MAXLINE], port[MAXLINE];
socklen_t clientlen;
struct sockaddr_storage clientaddr;
@@ -35,11 +39,23 @@
Getnameinfo((SA *) &clientaddr, clientlen, hostname, MAXLINE,
port, MAXLINE, 0);
printf("Accepted connection from (%s, %s)\n", hostname, port);
- doit(connfd); //line:netp:tiny:doit
- Close(connfd); //line:netp:tiny:close
+
+ connfdp = (int*)Malloc(sizeof(int));
+ *connfdp = connfd;
+ Pthread_create(&tid, NULL, thread, connfdp);
}
}
+void *thread(void *vargp) {
+ int connfd = *(int*)vargp;
+ Pthread_detach(Pthread_self());
+ Free(vargp);
+
+ doit(connfd);
+ Close(connfd);
+ return NULL;
+}
+
太长不写
太长不写