返回void指针作为线程返回

时间:2016-04-12 09:12:28

标签: c linux multithreading

这是来自apue

的摘录示例
private void open_ethernet_connection()
{
    byte connected = 0;

    TcpClient client = new TcpClient();
    try
    {

        IAsyncResult result = client.BeginConnect(textBox_IP.Text.Substring(0, textBox_IP.Text.IndexOf(",")), GlobalClass.port, null, null);
        bool success = result.AsyncWaitHandle.WaitOne(1000, true);

        if (!success)
        {
            connected = 0;
            client.Close();
            Response.Write("Failed to connect");
        }
        else connected = 1;

        if (connected == 1)
        {
            ns = client.GetStream();
            ns.ReadTimeout = 1000;
            SerBuf[0] = (byte)commands.GET_VER;     // get version command for ETH RLY16/02, returns software version
            transmit(1);
            receive(3);
            module_version = SerBuf[2];  //print the software version on screen
            device_found = true;
        }
    }
    catch (SocketException)
    {
        if (selected_port == "Custom IP")
        {
            Response.Write("Unable to connect to module at " + GlobalClass.ipaddress);
        }
        else Response.Write("Unable to connect to module at " + selected_port);
        return;
    } 
}

在这个例子中我不清楚两件事。

我将#include <pthread.h> #include <errno.h> #include <unistd.h> #include <stdio.h> void err_exit(const char* text){ char buf[200]; sprintf(buf, text); perror(buf); abort(); } void * thr_fn1(void *arg) { printf("thread 1 returning \n"); return ((void *)1); //This is returning the pointer to 1. //Is this address somewhat special? } int main(int argc, char *argv[]) { int err; pthread_t tid1; void *tret; err = pthread_create(&tid1, NULL, thr_fn1, NULL); if (err != 0) { err_exit("can't create thread 1"); } err = pthread_join(tid1, &tret); if (err != 0) { err_exit("can't join with thread 1"); } printf("Return of thread 1 %ld\n", (long)tret); return 0; } 解释为return ((void *)1);。为什么这样可以?选择这样的任意内存位置并将其视为退出状态?

return a void pointer pointing to address 1返回的printf("Return of thread 1 %ld\n", (long)tret);,现在为((void *)1),我们会将其从tret延伸到long。为什么在此源代码中提供了足够的信息,以便我们可以安全地使用char

1 个答案:

答案 0 :(得分:4)

将一个整数转换为void指针是实现定义的:

  

6.3.2.3指针

     
      
  1. 整数可以转换为任何指针类型。除非事先指明,否则   结果是实现定义的,可能没有正确对齐,可能不指向   引用类型的实体,可能是陷阱表示。
  2.   

(在陷阱表示的情况下,行为未定义。)

再次生成指向整数的指针也是实现定义的。在投放到1之前void*的类型实际上是int而不是char,但这不再重要,因为对象的类型是void*它正在转换为long

  
      
  1. 任何指针类型都可以转换为整数类型。除非事先指明,否则   结果是实现定义的。如果结果无法以整数类型表示,   行为未定义。结果不必在任何整数的值范围内   类型。
  2.   

返回的正确方法是返回指向具有静态或分配存储持续时间的对象的指针。由于您返回错误代码,我们可以假设它们数量有限,因此const静态对象可以工作:

void* thr_fn1(void* arg)
{
    printf("thread 1 returning \n");
    static const long ok_return = 1;
    return (void*)&ok_return;
}

打印对象是不同的,因为我们有一个指向长对象的有效指针:

printf("Return of thread 1 %ld\n", *(const long*)tret);