char content[100]; sprintf(content, "201XXXXXPROC1"); write(fd, content, sizeof(content)); printf("Child process write content: %s\n", content); close(fd); sem_post(sem); exit(0); } else { // Parent process pid_t pid2 = fork(); if (pid2 < 0) { perror("fork"); exit(1); } else if (pid2 == 0) { // Child process 2 sem_wait(sem); char *file = "MYFILE2"; int fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, 0666); if (fd < 0) { perror("open"); exit(1); } char content[100]; sprintf(content, "201XXXXXPROC2"); write(fd, content, sizeof(content)); printf("Child process 2 write content: %s\n", content); close(fd); sem_post(sem); exit(0); } else { // Parent process int status; waitpid(pid, &status, 0); waitpid(pid2, &status, 0); sem_close(sem); sem_unlink(argv[1]); printf("Parent process exit\n"); exit(0); } } } 写注释
时间: 2024-02-10 21:17:00 浏览: 46
这是一个使用信号量实现进程同步的程序。程序中创建了一个 POSIX 信号量,用于控制进程的访问。首先,父进程通过调用 `fork()` 创建了两个子进程。每个子进程都会在等待信号量的操作中阻塞,直到父进程释放信号量。当父进程完成进程创建后,通过调用 `sem_post()` 释放信号量,允许子进程执行。子进程执行完毕后,通过调用 `sem_wait()` 再次等待信号量的释放。程序最后通过调用 `waitpid()` 等待子进程的结束,并通过调用 `sem_close()` 和 `sem_unlink()` 清理信号量。
相关问题
写出以下代码在Linux系统下的输出结果:#include <string.h> int main() { int i,r,p1,p2,fd[2]; char buf[50],s[50]; memset(buf,0,sizeof(buf)); memset(s,0,sizeof(s)); pipe(fd);//创建管道 while((p1=fork())==-1);//创建子进程直至成功 if(p1==0)//当前为子进程p1时进入分支 { lockf(fd[1],1,0);//锁定写入端 sprintf(buf,"from child p1\n"); printf("child p1\n"); write(fd[1],buf,50);//将buf中字符写入管道 sleep(3);//睡眠3秒,让父进程读管道 lockf(fd[1],0,0);//释放管道写入端 exit(0);//关闭p1 } else//父进程返回,执行父进程 { while((p2=fork())==-1);//建立子进程p2 if(p2==0)//执行p2 { lockf(fd[1],1,0); sprintf(buf,"from child p2\n"); printf("child p2\n"); write(fd[1],buf,50); sleep(3);//睡眠等待 lockf(fd[1],0,0);//释放写入端 exit(0);//关闭p2 } wait(0); if(r=read(fd[0],s,50==-1))//读取失败 printf("error\n"); else printf("%d %s\n",r,s); wait(0); if(r=read(fd[0],s,50)==-1) printf("error\n"); else printf("%d %s\n",r,s); wait(0); if (r=read(fd[0],s,50==-1)) printf("error\n"); else printf("%s\n",s); exit(0);//关闭父进程
该程序的输出结果可能会变化,因为它依赖于进程调度和管道的实现。但是,根据程序的逻辑和语法,可以推断出以下的可能输出结果:
child p1
child p2
50 from child p1
50 from child p2
error
解释:
该程序创建了两个子进程 p1 和 p2,并在管道中写入了一些数据。在父进程中,通过读取管道中的数据来获取子进程写入的信息。
首先,p1 写入了 "from child p1\n",然后睡眠 3 秒,等待父进程读取管道。接着,p2 写入了 "from child p2\n",也睡眠 3 秒,等待父进程读取管道。这两个子进程都释放了管道的写入端。
在父进程中,首先等待 p2 进程结束,然后从管道中读取了 p1 写入的信息 "from child p1\n",并打印了读取的字符数和字符串内容。接着,父进程等待 p1 进程结束,再次从管道中读取了 p2 写入的信息 "from child p2\n",并打印了读取的字符数和字符串内容。最后,父进程再次尝试从管道中读取数据,但此时管道已经没有数据可读,因此输出 "error"。最后,程序结束并关闭所有进程。
请检查一下如下代码是否存在问题 int https_post(const char *cert_path, const char *url, const char *body, char *response) { int sockfd, len; struct sockaddr_in dest; struct hostent *host; SSL_CTX *ctx; SSL *ssl; char request[MAX_BUF_SIZE], buf[MAX_BUF_SIZE]; // 初始化OpenSSL库 SSL_library_init(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); // 解析主机名 printf("66666666 %s\n", url); host = gethostbyname(url); //printf("Child process created with PID %s\n", host); if (host == NULL) { perror("gethostbyname"); return -1; } // 创建套接字 printf("Child process created with PID %d\n", 2222); sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror("socket"); return -1; } // 设置目标地址 bzero(&dest, sizeof(dest)); dest.sin_family = AF_INET; dest.sin_port = htons(443); dest.sin_addr.s_addr = *(long*)host->h_addr; // 连接服务器 printf("Child process created with PID %d\n", 3333); if (connect(sockfd, (struct sockaddr*)&dest, sizeof(dest)) != 0) { perror("connect"); return -1; } ctx = SSL_CTX_new(TLS_method()); // 设置支持的协议版本为 TLSv1.2 SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION); SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION); // 创建SSL上下文 //ctx = SSL_CTX_new(TLSv1_2_client_method()); printf("Child process created with PID %d\n", 4444); if (ctx == NULL) { perror("SSL_CTX_new"); return -1; } // 加载证书 printf("Child process created with PID %d\n", 5555); if (SSL_CTX_load_verify_locations(ctx, cert_path, NULL) != 1) { perror("SSL_CTX_load_verify_locations"); return -1; } // 创建SSL printf("Child process created with PID %d\n", 6666); ssl = SSL_new(ctx); if (ssl == NULL) { perror("SSL_new"); return -1; } printf("Child process created with PID %d\n", 7777); // 将套接字绑定到SSL SSL_set_fd(ssl, sockfd); printf("Child process created with PID %d\n", 9999); // SSL握手 if (SSL_connect(ssl) == -1) { perror("SSL_connect"); return -1; } // 构造HTTP请求 printf("Child process created with PID %d\n", 8888); sprintf(request, "POST / HTTP/1.1\r\n" "Host: %s\r\n" "Content-Type: application/json\r\n" "Content-Length: %d\r\n" "\r\n" "%s", url, strlen(body), body); // 发送HTTP请求 printf("Child process created with PID %d\n", 00000); SSL_write(ssl, request, strlen(request)); // 接收HTTP响应 len = SSL_read(ssl, buf, MAX_BUF_SIZE); // 关闭SSL和套接字 SSL_free(ssl); close(sockfd); // 处理响应 strncpy(response, buf, len); response[len] = '\0'; // 清理OpenSSL库 SSL_CTX_free(ctx); EVP_cleanup(); printf("Child process created with PID %d\n", 11111); return 0; }
这段代码存在一些问题,比如:
1. 在 SSL_CTX_new() 函数之前需要调用 SSL_library_init()、SSL_load_error_strings() 和 OpenSSL_add_all_algorithms(),来初始化 OpenSSL 库。
2. 在 gethostbyname() 函数返回 NULL 时,应该使用 herror() 或者 perror() 函数来输出错误信息。
3. 在 socket() 函数返回 -1 时,应该使用 perror() 函数来输出错误信息。
4. 在 SSL_CTX_new() 函数返回 NULL 时,应该使用 ERR_error_string() 函数来输出错误信息。
5. 在 SSL_CTX_load_verify_locations() 函数返回 -1 时,应该使用 ERR_error_string() 函数来输出错误信息。
6. 在 SSL_new() 函数返回 NULL 时,应该使用 ERR_error_string() 函数来输出错误信息。
7. 在 SSL_set_fd() 函数返回 -1 时,应该使用 ERR_error_string() 函数来输出错误信息。
8. 在 SSL_connect() 函数返回 -1 时,应该使用 ERR_error_string() 函数来输出错误信息。
9. 在 SSL_read() 函数返回 -1 时,应该使用 ERR_error_string() 函数来输出错误信息。
10. 在 SSL_free() 函数之前应该先判断 ssl 是否为 NULL。
11. 在 SSL_CTX_free() 函数之前应该先判断 ctx 是否为 NULL。
12. 在 EVP_cleanup() 函数之前应该先调用 ERR_free_strings() 函数来释放 OpenSSL 库中的错误字符串。
阅读全文