通过socketpair+select实现线程同步的用法代码
2023-12-14 20:32:56
1,socketpair详细用法说明
socketpair()是一个Unix/Linux系统调用,用于创建一个本地端对(socket pair)。它创建两个已连接的socket描述符,用于在同一进程中的两个不同线程之间进行通信。
以下是socketpair()函数的详细用法说明:
#include <sys/socket.h>
#include <unistd.h>
int socketpair(int domain, int type, int protocol, int sv[2]);
参数说明:
domain:指定要使用的协议域,通常是AF_UNIX或AF_INET。
type:指定要创建的套接字的类型,可以是SOCK_STREAM(流套接字)或SOCK_DGRAM(数据报套接字)。
protocol:指定要使用的具体协议,对于大多数应用程序来说,通常设置为0。
sv:这是一个长度为2的整数数组,用于存储创建的两个套接字的描述符。
返回值:
如果成功,socketpair()返回0,否则返回-1并设置errno表示错误码。
2,select的用法说明
Select则是一种用于监视多个文件描述符(包括套接字)的变化情况的方法。它通常用于非阻塞式I/O操作,可以同时监视多个文件描述符的状态(如可读、可写或异常等)。Select通常用于异步或事件驱动的程序中,可以提高程序的效率和响应速度。
在使用Select时,需要创建一个select()函数,指定要监视的文件描述符集合以及等待的时间。在select()函数返回后,可以根据文件描述符的状态进行相应的读写操作。Select的使用需要结合事件循环和回调函数等机制来实现异步I/O操作。
需要注意的是,Socketpair和Select的使用场景和目的不同,应该根据具体的需求选择合适的工具。同时,在使用Socketpair和Select时,需要注意它们的错误处理和异常情况的处理,以确保程序的稳定性和可靠性。
3,使用socketpair和select实现线程同步
下面是一个使用socketpair和select实现两个线程同步的参考代码:
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <sys/select.h>
#include <sys/time.h>
#define BUFFER_SIZE 1024
void *thread_func(void *arg) {
int sockfd = *((int *)arg);
char buffer[BUFFER_SIZE];
fd_set readfds;
struct timeval tv;
int n;
char message[] = "Hello from sub thread";
while (1) {
FD_ZERO(&readfds);
FD_SET(sockfd, &readfds);
tv.tv_sec = 1; // 设置超时时间为1秒
tv.tv_usec = 0;
n = select(sockfd + 1, &readfds, NULL, NULL, &tv);
if (n == -1) {
perror("select");
exit(EXIT_FAILURE);
} else if (FD_ISSET(sockfd, &readfds)) {
n = recv(sockfd, buffer, BUFFER_SIZE, 0);
buffer[n] = '\0';
printf("Thread received: %s\n", buffer);
} else {
printf("Timeout\n");
break;
}
send(sockfd, message, strlen(message), 0);
}
close(sockfd);
return NULL;
}
int main() {
int sockfd[2];
pthread_t thread;
char message[] = "Hello from main thread";
// 创建socketpair
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd) == -1) {
perror("socketpair");
exit(EXIT_FAILURE);
}
// 创建线程并传递socket的文件描述符
if (pthread_create(&thread, NULL, thread_func, &sockfd[0]) != 0) {
perror("pthread_create");
exit(EXIT_FAILURE);
}
// 发送消息给线程,并等待接收消息的超时时间设置为1秒
send(sockfd[1], message, strlen(message), 0);
struct timeval tv;
tv.tv_sec = 1; // 设置超时时间为1秒
tv.tv_usec = 0;
fd_set readfds;
int n;
while (1) {
FD_ZERO(&readfds);
FD_SET(sockfd[1], &readfds);
n = select(sockfd[1] + 1, &readfds, NULL, NULL, &tv);
if (n == -1) {
perror("select");
exit(EXIT_FAILURE);
} else if (FD_ISSET(sockfd[1], &readfds)) {
n = recv(sockfd[1], buffer, BUFFER_SIZE, 0);
buffer[n] = '\0';
printf("Main received: %s\n", buffer);
break; // 接收消息,跳出循环等待线程发送消息或超时后退出线程处理函数。
} else {
printf("Timeout\n"); // 超时后输出提示信息。可以根据需求进行其他处理。例如,可以设置一个标志位表示超时,在主线程中检查该标志位并做出相应处理。同时,也可以在超时后直接退出线程处理函数。根据具体需求进行选择。这里简单输出提示信息。
}
}
文章来源:https://blog.csdn.net/jiangchaobing_2017/article/details/135002407
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!