UDS(Unix Domain Socket)用在线程间通信Demo

UDS是Linux较为常用的一种IPC方式,具体用法参考 https://blog.csdn.net/z2066411585/article/details/78966434/ 

    博主今天为验证UDS是否可用于线程之间的通信,写了一个Demo。将主线程作为服务端,子线程作为客户端,主线程向子线程传递数据(该数据存放于堆区),传递后立马在主线程中释放,再在子线程中访问(目的在于验证数据的传递是否为内容的拷贝),代码如下(testUDSacrossThreads.c):

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<sys/un.h>
#include<errno.h>
#include<stddef.h>
#include<unistd.h>
 
 
#include <pthread.h>
 
 
const char* filename = "uds-accross-thread-test";
int fd;
 
 
void *thread_enter()
{
    int subthreadtid = pthread_self();
    printf("subthread: %u, access fd in mainthread %d\n", subthreadtid, fd);    // try to access variable in main thread? 
    /* sleep 10s here to wait for main thread */
    sleep(10);
 
 
    struct sockaddr_un un;
    int sock_fd;
    char* buf;// = (char*)malloc(sizeof(char) * 1024);
    
    un.sun_family = AF_UNIX;
    strcpy(un.sun_path, filename);
    /* create socket */
    sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
    if(sock_fd < 0)
    {
        printf("failed to create socket in subthread\n");
        exit(-1);    // how to perform?
    }
    if(connect(sock_fd, (struct sockaddr*)&un, sizeof(un)) < 0)
    {
        printf("failed to connect in subthread\n");
        exit(-1);
    }
    int ret = recv(sock_fd, buf, 1024, 0);
    if(ret < 0)
    {
        printf("failed to recv in subthread\n");
        exit(-1);
    }
    // print for 3 times with interval 5s
    for(int i = 0; i < 3; ++i)
    {
        sleep(5);
        printf("data_to_send received in subthread: %s\n", buf);
    }
 
 
    return NULL;
}
 
 
int main()
{
    int maintid = pthread_self();
    pthread_t subthread;
    char* data_to_send;
 
 
    /* create a socket */
    fd = socket(AF_UNIX, SOCK_STREAM, 0);    
    printf("main thread: create socket, fd=%d\n");
    /* create subthread */
    int rc = pthread_create(&subthread, NULL, thread_enter, NULL);
    printf("main thread: %u, create subthread: %u\n", maintid, subthread);
 
 
    /* use Unix domain socket to communicate with subthread */
    int /*fd,*/ newfd;                            //    fd: use to listen, newfd: present the connection socket
    struct sockaddr_un un;                    
    
    if(fd < 0)
    {
        printf("failed to create socket\n");
        exit(1);
    }
    un.sun_family = AF_UNIX;
    unlink(filename);
    strcpy(un.sun_path, filename);
    
    /* bind */
    if(bind(fd, (struct sockaddr*)&un, sizeof(un)) < 0)
    {
        printf("failed to bind\n");
        exit(1);
    }
    
    /* listen */
    if(listen(fd, 2) < 0)
    {
        printf("failed to listen\n");
        exit(1);
    }
 
 
    data_to_send = (char*)malloc(sizeof(char) * 20);
    strcpy(data_to_send, "hello world");
    int data_size = sizeof("hello world");
    printf("main thread: after strcpy data_to_send %s\n", data_to_send);
    /* accept & send data_to_send */
    do    
    {
        struct sockaddr_un subthread_addr;
        newfd = accept(fd, NULL, NULL);    //    Is this blocked? Yes, it is blocked.
        if(newfd < 0)
        {
            printf("failed to accept\n");
            exit(1);
        }
        send(newfd, data_to_send, data_size, 0);
 
 
        // free data_to_send
        free(data_to_send);
    } while(0);
 
 
    for(int i = 0; i < 30; ++i)
    {
        printf("main thread...\n");
        sleep(1);
    }
    pthread_join(subthread, NULL);
    printf("main thread: exit\n");
}
编译及运行:

gcc -o ./testUDSacrossThreads testUDSacrossThreads.c -pthread -std=c99

./testUDSacrossThreads

    写这个Demo在于验证两点猜想:

    1. 从线程1(此处是main线程)通过UDS传递到线程2的数据是否通过内容的拷贝?(是)

    2. UDS是否可以用于线程间的通信?(可以)

    对于上述第一点猜想,我在子线程中直接用一个没有动态申请内存指针去接主线程过来的数据(显然这是不正确、不良好的做法),也能接住。并且主线程释放内存后,子线程中仍能访问到该数据,我想大概是内核的行为吧(没有深究)?

 

参考:

1. UDS(Unix Domain Socket)用在线程间通信Demo

2. Linux下进程间通讯方式 - UNIX Domain Socket

3. 进程间通信之UNIX域套接字(UDS)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值