• 多线程传参问题记录


    正确的线程传参:

     
    #include <pthread.h>
    #include <errno.h>
    #include <stdio.h>
     
     
    void* say_hello(void* fd)
    {
        //对传入的参数进行强制类型转换,由无类型指针变为整形数指针,然后再读取;
        int connectfd =*((int *)fd);
        printf("thread connectfd:%d
    ",connectfd);
        pthread_exit(NULL);
    
    }
     
    int main()
    {
        pthread_t thread_recv;
        
          int i = -3;
        int ret = pthread_create(&thread_recv, NULL, say_hello, (void *)&i);//传入的时候必须强制转换为void* 类型,即无类型指针
        printf("current pthread id = %d
    ",thread_recv);
        if (ret != 0)
        {
           printf("pthread_create error: error_code=%d",ret);
        }
        ret = pthread_join(thread_recv,NULL);
        if(ret) {
            perror ("pthread_join join error:");
            return ret;
        }
        while(1);
        
    }

    优化代码这样写时,线程的传参是错误的,不知道问题出在哪了。

     
    #include <pthread.h>
    #include <errno.h>
    #include <stdio.h>
     
    pthread_t thread_recv;
     
    void* say_hello(void* fd)
    {
        //对传入的参数进行强制类型转换,由无类型指针变为整形数指针,然后再读取;
        int connectfd =*((int *)fd);
        printf("thread connectfd:%d
    ",connectfd);
        pthread_exit(NULL);
    
    }
     
    void thread_init(int val)
    {
        int ret = pthread_create(&thread_recv, NULL, say_hello, (void *)&val);//传入的时候必须强制转换为void* 类型,即无类型指针
        printf("current pthread id = %d
    ",thread_recv);
        if (ret != 0)
        {
           printf("pthread_create error: error_code=%d",ret);
        }
    }
    int main()
    {
      
        int ret = -1;
          int i = -3;
        thread_init(i);
        ret = pthread_join(thread_recv,NULL);
        if(ret) {
            perror ("pthread_join join error:");
            return ret;
        }
        while(1);
        
    }

    后面仔细goole检查了下,解决办法

    https://www.jianshu.com/p/9444c6a5e102

    函数传参时,避免主程序因为等待线程而阻塞,使用pthread_detach(pid)函数使线程函数自运行。则该线程运行结束后会自动释放所有资源。使用函数传参时,注意以下几个易错点:
     1. 传递的参数类型是个(void型)指针。
     2. 参数传递中,不能使用局部变量int a, 以&a 的方式传参。可采用

    int a = 5;//局部变量
    pthread_create(pid,  NULL,  thread_func,  (void  *)a);
    ........
    void *thread_func(void *argc)
    {
        ......
           b = (int )argc;//实现局部变量的对线程函数的传参
        ......
    }

    但此时会出现警告: warning: cast from pointer to integer of different size

    网上解决办法:

    方法一:

    如果这样定义会出现如下warning提示:
    (void*)virt_to_bus(yuv_frames)
    warning: cast to pointer from integer of different size
    如何去掉warning呢,
    (void*)(long)virt_to_bus(yuv_frames)
    这样warning就去掉了  
    方法二:
    https://blog.csdn.net/mybelief321/article/details/9375929
    res=pthread_create(&thread[no],NULL,(void *)thrd_func,(void*)no);
    thread.c: In function ‘main’:
    thread.c:38:57: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]

    将(void*)no,修改成&no,就可以了,如下修改后的代码
    res=pthread_create(&thread[no],NULL,(void *)thrd_func,&no);

    采用方法一修改后的代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <string.h>
    #include <stdbool.h>
    #include <errno.h>
    #include <sys/socket.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <signal.h>
    #include <resolv.h>
    #include <fcntl.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <pthread.h>
    #include <semaphore.h>
    
    
    /************************************************************* 
    * 函数名称: Recv_Thread_entery
    * 功能描述: 接收状态接收机B的数据并处理(命令或消息)
                receive from sockfd_StatusA
    * 参数列表: 套接字
    * 返回结果: 无 
    **************************************************************/ 
    void * Recv_Thread_entery(void* fd)  
    {
        int connectfd =*((int *)(&fd));//(int)fd;
        printf("thread connectfd:%d
    ",connectfd);
        pthread_exit(NULL);
    }
    
    
    
    /************************************************************* 
    * 函数名称: Recv_Thread_Init
    * 功能描述: 状态接收机A初始化线程
    * 参数列表: 无
    * 返回结果: 创建线程成功为0 
    **************************************************************/ 
    int Recv_Thread_Init(int connectfd)
    {
        pthread_t recv_id;
        printf("Recv_Thread_Init:%d
    ",connectfd);
        int ret;
        //return 0: On success
        ret=pthread_create(&recv_id,NULL,Recv_Thread_entery,(void*)(long)(connectfd));//(void*)
        if(ret!=0){
            perror ("Create recv pthread:");
            return ret;
            
        }
        pthread_detach(recv_id);
        return 0;
    }
    
    int main()
    {
        
        int ret = -1;
        int connectfd = 3;
        Recv_Thread_Init(connectfd);
    #if 0
        pthread_t recv_id;
        /**TCP客户端接收线程初始化(接收:来自192.168.33.35数据并分析)**/
        ret=pthread_create(&recv_id,NULL,Recv_Thread_entery,(void*)(&connectfd));//(void *)&connectfd);
        if(ret!=0){
            perror ("Create recv pthread:");
            return ret;
            
        }
    
        ret = pthread_join(recv_id,NULL);
        if(ret) {
            perror ("pthread_join join error:");
            return ret;
        }
    #endif
    
        while(1) {sleep(5);}
        return 0;
    }

      

  • 相关阅读:
    MySql 应用语句
    MySql 存储过程 退出
    MySql 存储过程 光标只循环一次
    MySql获取两个日期间的时间差
    VM VirtualBox 全屏模式 && 自动缩放模式 相互切换
    区分不同操作系统、编译器不同版本的宏
    debian下配置网络 安装无线网卡驱动 Broadcom BCMXX系列
    YII 主题设置
    Unix线程概念、控制原语、属性
    远程IPC种植木马
  • 原文地址:https://www.cnblogs.com/shuqingstudy/p/10395962.html
Copyright © 2020-2023  润新知