sun 上关于 pthread_create 的 extern "C" 警告的讨论

Solaris线程创建警告

Solaris 简单程序:

 

#include  < pthread.h >
#include 
< stdio.h >

/* thread function */
void *  start_routine( void *  arg)
{
        printf(
"thread %d running... ",*(int*)arg);
        
return NULL;
}


int  main()
{
        pthread_t tid1;
        
int arg = 1;
        
int ret;
        ret 
= pthread_create(&tid1,NULL,start_routine,(void*)&arg);
        
return ret;
}

调用 CC thread1.cpp,

警告(记时错误): 正在将 void*(*)(void*) 传递给调用 pthread_create(unsigned*, const _pthread_attr*, extern "C" void*(*)(void*), void*) 时使用的类型为 extern "C" void*(*)(void*) 的形式参数 3. 

有人认为是sun的bug,有人认为不是。

解决办法

在线程函数start_routine前增加extern "C"

Warning (Anachronism)   
Nov 19, 2000 5:24 AM

Click to email this message

 
 
Hi all,

I'm getting the following compiler warning in certain cases:

Warning (Anachronism): Formal
argument 3 of type extern "C" void*(*)(void*) in call to
pthread_create(unsigned*, const _pthread_attr*,
extern "C" void*(*)(void*), void*) is being passed void*(*)(void*).

This happens when the C function I'm calling (in this case pthread_create()), expects a function as a parameter. The function I am passing it is a normal global function. The warning is coming from me not declaring my function as extern "C". What are the consequences of this warning? I've never had any problems ignoring it, but maybe there could be some... Am I safe to ignore?

Thanks!
 
jrpratt
Posts:1
Registered: 6/5/97
Warning (Anachronism)   
Dec 28, 2000 12:37 PM (reply 1 of 12)

Click to email this message

 
Not sure what the consequences are but I've run into the same warnings. There is a section in the C++ Migration guide that specifically addresses this issue. I recommend looking at the migration guide for more information.
 
flahdiri
Posts:1
Registered: 2/3/99
Re: Warning (Anachronism)   
May 15, 2002 9:32 AM (reply 2 of 12)

Click to email this message

 
Hi,

Has anyone figured this problem out ? I am getting the same warning (using C++ 5.0 and pthread.h).
Please post answers.

Thanks


--
Farid


> Hi all,
>
> I'm getting the following compiler warning in certain
> cases:
>
> Warning (Anachronism): Formal
> argument 3 of type extern "C" void*(*)(void*) in
> n call to
> pthread_create(unsigned*, const _pthread_attr*,
> extern "C" void*(*)(void*), void*) is being passed
> d void*(*)(void*).
>
> This happens when the C function I'm calling (in this
> case pthread_create()), expects a function as a
> parameter. The function I am passing it is a normal
> global function. The warning is coming from me not
> declaring my function as extern "C". What are the
> consequences of this warning? I've never had any
> problems ignoring it, but maybe there could be some...
> Am I safe to ignore?
>
> Thanks!

 
AnwerAbbas
Posts:17
Registered: 1/30/01
Re: Warning (Anachronism)   
May 15, 2002 9:30 PM (reply 3 of 12)

Click to email this message

 
Its always a good idea to remove all the warnings from c/c++ program. I treat them as errors.
Declare the function, you are passing as an argument to pthread_create, as extern "C" fn();
And it will take care of your warnings.
Recently I have done this in upgrading the code from C++ 4.2 to 5.3.
Anwer.
 
rick_campbell
Posts:1
Registered: 12/10/99
Re: Warning (Anachronism)   
May 23, 2002 1:17 PM (reply 4 of 12)

Click to email this message

 
> Its always a good idea to remove all the warnings from
> c/c++ program. I treat them as errors.
> Declare the function, you are passing as an argument
> to pthread_create, as extern "C" fn();
> And it will take care of your warnings.
> Recently I have done this in upgrading the code from
> C++ 4.2 to 5.3.
> Anwer.

It is perfectly alright to define a static function and use it as a functional parameter. The SparcWorks compiler is incorrectly confusing linkage (extern "C") with type (void* (*) (void*)) amd issuing a bogus warning.

The code is correct, the compiler is wrong.

 
joshwalker
Posts:60
Registered: 12/4/01
Re: Warning (Anachronism)   
May 23, 2002 1:55 PM (reply 5 of 12)

Click to email this message

 
Actually, I think the compiler is correct. Look at the C++ standard, last sentence of 7.5/1:

<quote>
Two function types with different language linkages are distinct types even if they are otherwise identical.
</quote>

This clearly says that language linkage is part of the type. This makes sense, because functions in different languages might use different conventions for parameter passing or be otherwise incompatible.

The safe and portable thing to do is declare the function you pass to pthread_create as extern "C".

Josh Walker


 
RobbieRAltera
Posts:1
Registered: 5/24/02
Re: Warning (Anachronism)   
May 24, 2002 11:37 AM (reply 6 of 12)

Click to email this message

 
We should be able to turn these anachronistic warnings off. Why doesn't -w disable these warnings. I would prefer it if Sun would let developers decide which warnings can be ignored and which ones should not. Don't force these warnings down our throats.

 
joshwalker
Posts:60
Registered: 12/4/01
Re: Warning (Anachronism)   
May 24, 2002 12:04 PM (reply 7 of 12)

Click to email this message

 
I agree that it is important to be able to disable warnings you don't want to see.

But note that the code causing the warning is anachronistic, not the warning ;)

Josh
 
LYLeung
Posts:3
Registered: 5/24/02
Re: Warning (Anachronism)   
May 24, 2002 2:55 PM (reply 8 of 12)

Click to email this message

 
I also ran into this problem but even after declaring the called function as extern "C", I am still getting the warning. Using the posted code as an example, I did the following in the corresonding header file:

extern "C" pthread_create (.....)

But the warning continues. Did I miss something here?

Thanks.

Lance
 
AnwerAbbas
Posts:17
Registered: 1/30/01
Re: Warning (Anachronism)   
May 29, 2002 11:20 PM (reply 9 of 12)

Click to email this message

 
You do not have to declare ptherad_create as extern "C".
The function in the argument of pthread_create needs to be declare as extern C.
Example.
extern "C" myFunction(........)
void main()
{
ptherad_create(..., &myFunction,...);

}

Hopefully it will help.


 
singhaia
Posts:2
Registered: 11/6/01
Re: Warning (Anachronism)   
Jun 7, 2002 8:26 AM (reply 10 of 12)

Click to email this message

 
Hi everyone!!!

I have spent some time banging my head for such warnings. Defining functions as extern "C" solves most of the problems. But in case of a static function being passed as a parameter which accepts and extern "C" argument the issue can be a bit tricky ..Earlier, all static fuctions in C++ had extern "C" linkage so no question of warnings..but now static functions dont have extern C linkage so we are stuck with these warnings.
 
joshwalker
Posts:60
Registered: 12/4/01
Re: Warning (Anachronism)   
Jun 7, 2002 11:15 AM (reply 11 of 12)

Click to email this message

 
Somehow I doubt that static functions ever had extern "C" linkage. Functions declared extern "C" cannot be overloaded, so this would be pretty limiting. Perhaps the compiler just didn't issue a warning before.

Josh

 
edwin_chen
Posts:1
Registered: 7/12/02
Re: Warning (Anachronism)   
Jul 12, 2002 2:47 PM (reply 12 of 12)

Click to email this message

 
I worked around the 'passing static methods' issue by adding the following lines:


typedef void* (*CVoidFunction)(void*); // extern "C++" linkage

extern "C" int CreateThread( pthread_t*& pThread, CVoidFunction pVoidFunction, void* pArgument )
{
// Create the thread
const int nResult = pthread_create( pThread,
(const pthread_attr_t*)0,
(void*(*)(void*))pVoidFunction, // cast to extern "C" void* (*)( void* )
pArgument );

return nResult;
}


It will then be possible to create threads with static methods and avoid compiler warnings!

很好,这是我对你代码添加的注释,帮我修改成多进程完成实现一个简单的web server(端口80)承载附件的web。LINUX C语言。 附件为 css,data,images,img,js, Index.html,Work.html,Contack.html,About.html 。代码注释风格与我给你的相同。/* Copyright(c) Lianzhou International Co.Ltd. * * file threaded_server.c * brief This is a simple muti-threade server. * * author Sun Haoming * version 1.0.0 * date 25Aug14 * * history * \arg 1.0.0, 25Aug14, Sun Haoming, Create the file. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <pthread.h> #include <sys/stat.h> #include <fcntl.h> #include <arpa/inet.h> /**************************************************************************************************/ /* DEFINES */ /**************************************************************************************************/ #define PORT 80 #define BUFFER_SIZE 2048 /**************************************************************************************************/ /* TYPES */ /**************************************************************************************************/ /**************************************************************************************************/ /* EXTERN_PROTOTYPES */ /**************************************************************************************************/ /**************************************************************************************************/ /* LOCAL_PROTOTYPES */ /**************************************************************************************************/ const char *get_content_type(const char *path); /**************************************************************************************************/ /* VARIABLES */ /**************************************************************************************************/ /**************************************************************************************************/ /* LOCAL_FUNCTIONS */ /**************************************************************************************************/ /* 根据拓展名返回类型 */ const char *get_content_type(const char *path) { const char *ext = strrchr(path, '.'); /* strrchr从末尾查找至. */ if (ext) { if (strcmp(ext, ".html") == 0) return "text/html"; if (strcmp(ext, ".css") == 0) return "text/css"; if (strcmp(ext, ".js") == 0) return "application/javascript"; if (strcmp(ext, ".png") == 0) return "image/png"; if (strcmp(ext, ".jpg") == 0) return "image/jpeg"; } return "application/octet-stream"; /*默认返回二进制流*/ } /* 发送HTTP响应给客户端 */ void send_response(int client_fd, const char *path) { char header[BUFFER_SIZE]; /*响应头buffer*/ char buffer[BUFFER_SIZE]; /*内容buffer*/ struct stat st; /*文件状态*/ /* 文件不存在 */ if (stat(path, &st) == -1) { printf("该文件未找到:%s\n", path); /* 404 文件头 */ snprintf(header, BUFFER_SIZE, "HTTP/1.1 404 Not Found\r\n" "Content-Type: text/html\r\n" "\r\n" "<h1>404 Not Found</h1>"); send(client_fd, header, strlen(header), 0); return; } /*读取文件*/ int fd = open(path, O_RDONLY); if (fd < 0) { printf("打开该文件失败: %s\n", path); return; } /* 200 OK 文件头 */ snprintf(header, BUFFER_SIZE, "HTTP/1.1 200 OK\r\n" "Content-Type: %s\r\n" "Content-Length: %ld\r\n" "\r\n", get_content_type(path), st.st_size); send(client_fd, header, strlen(header), 0); printf("发送文件: %s (大小: %ld 字节)\n", path, st.st_size); /*发送给客户端*/ ssize_t bytes_read; while ((bytes_read = read(fd, buffer, BUFFER_SIZE)) > 0) { send(client_fd, buffer, bytes_read, 0); } close(fd); } /*客户端请求线程*/ void *handle_client(void *arg) { int client_fd = *((int *)arg); char buffer[BUFFER_SIZE]; char path[BUFFER_SIZE] = "./"; /* 默认./ */ /*读取客户端请求*/ ssize_t bytes_read = read(client_fd, buffer, BUFFER_SIZE - 1); if (bytes_read <= 0) { printf("读取客户端请求失败\n"); close(client_fd); free(arg); return NULL; } buffer[bytes_read] = '\0'; /* 获取客户端IP */ struct sockaddr_in addr;/*地址结构*/ socklen_t addr_len = sizeof(addr);/*地址长度*/ getpeername(client_fd, (struct sockaddr*)&addr, &addr_len);/*获取当前socket的对端地址*/ char client_ip[INET_ADDRSTRLEN];/*存储IP*/ inet_ntop(AF_INET, &addr.sin_addr, client_ip, sizeof(client_ip));/*将二进制IP转为字符串*/ printf("收到来自 %s 的请求:\n%.*s\n", client_ip, (int)bytes_read, buffer); /* 获取GET请求 */ if (strncmp(buffer, "GET ", 4) == 0) { char *start = buffer + 4; char *end = strchr(start, ' '); /* 查找空格结束 */ if (end) { *end = '\0'; /* 根目录 */ if (strcmp(start, "/") == 0) { strcat(path, "Index.html"); } else { /* 拼接根目录+路径 */ strncat(path, start, BUFFER_SIZE - strlen(path) - 1); } } } send_response(client_fd, path); close(client_fd); free(arg); printf("请求处理完成\n"); return NULL; } /**************************************************************************************************/ /* PUBLIC_FUNCTIONS */ /**************************************************************************************************/ /**************************************************************************************************/ /* GLOBAL_FUNCTIONS */ /**************************************************************************************************/ int main() { int server_fd, client_fd; struct sockaddr_in address;/* 服务器结构地址 */ int addrlen = sizeof(address); printf("Web服务器启动,监听端口 %d \n", PORT); /* 创建套接字 */ if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { perror("创建套接字失败"); exit(EXIT_FAILURE); } address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT);/* 端口号 */ /* 绑定 */ if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("绑定端口失败"); exit(EXIT_FAILURE); } /* 监听 */ if (listen(server_fd, 10) < 0) { perror("监听失败"); exit(EXIT_FAILURE); } printf("服务器已启动\n"); /* 持续接收客户端连接*/ while (1) { if ((client_fd = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) { perror("接受连接失败"); continue; } printf("出现新的客户端连接\n"); /* 创建线程 */ pthread_t thread_id; int *new_sock = malloc(sizeof(int)); *new_sock = client_fd; if (pthread_create(&thread_id, NULL, handle_client, (void*)new_sock) < 0) { perror("创建线程失败"); close(client_fd); free(new_sock); } pthread_detach(thread_id); } return 0; }
最新发布
08-16
原来是因为大小写问题,现在的情况是我可以访问Index,但是点击其中的跳转失败,(首先注意我不懂前端)这个目录下一共只有Index.html About.html Contact.html Work.html,剩下css data images img js均为文件夹,我要做的成功效果只是在index中可以点击跳转另外三个html,是不是不用访问那些img等等? 现在代码是如下的/* Copyright(c) Lianzhou International Co.Ltd. * * file threaded_server.c * brief This is a simple muti-threade server. * * author Sun Haoming * version 1.0.0 * date 25Aug14 * * history * \arg 1.0.0, 25Aug14, Sun Haoming, Create the file. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <netinet/in.h> #include <sys/types.h> #include <sys/socket.h> #include <pthread.h> #include <arpa/inet.h> /**************************************************************************************************/ /* DEFINES */ /**************************************************************************************************/ #define BUFFER_SIZE 1024 #define PORT 80 #define CLIENTS_MAX 10 /*监听长度*/ /**************************************************************************************************/ /* TYPES */ /**************************************************************************************************/ /**************************************************************************************************/ /* EXTERN_PROTOTYPES */ /**************************************************************************************************/ /**************************************************************************************************/ /* LOCAL_PROTOTYPES */ /**************************************************************************************************/ /**************************************************************************************************/ /* VARIABLES */ /**************************************************************************************************/ /**************************************************************************************************/ /* LOCAL_FUNCTIONS */ /**************************************************************************************************/ const char *get_content_type(const char *path) { const char *ext = strrchr(path, '.'); if (ext) { if (strcmp(ext, ".html") == 0) return "text/html; charset=utf-8"; else if (strcmp(ext, ".css") == 0) return "text/css"; else if (strcmp(ext, ".js") == 0) return "js/js"; else if (strcmp(ext, ".png") == 0) return "image/png"; else if (strcmp(ext, ".jpg") == 0) return "img/jpg"; // 可以添加更多类型 } return "text/plain"; // 默认纯文本 } void *handle_client(void *arg){ int client_socket = *((int *)arg); char buffer[BUFFER_SIZE] = {0}; read(client_socket, buffer, BUFFER_SIZE); printf("Received request: %s\n", buffer); // 或者只打印第一行 /*解析 HTTP 请求行*/ char method[10], path[100], protocol[10]; sscanf(buffer, "%s %s %s", method, path, protocol); /*根路径设置*/ if(strcmp(path, "/") == 0) strcpy(path, "/Index.html"); char full_path[150] = {0}; sprintf(full_path, ".%s", path); FILE *file = fopen(full_path, "rb"); if(file == NULL){ char *not_found_response = "HTTP/1.1 404 Not Found\r\n\r\n"; write(client_socket, not_found_response, strlen(not_found_response)); } else { /*获取文件大小*/ fseek(file, 0 ,SEEK_END); long file_size = ftell(file); fseek(file, 0, SEEK_SET); /*构造http响应头*/ /* char header[] = "HTTP/1.1 200 OK\r\n" "Content-Type: text/html; charset=utf-8\r\n" "Connection: close\r\n" // 简化调试用close模式 "\r\n"; // 注意:必须有两个\r\n表示头结束 */ const char *content_type = get_content_type(path); char header[1024]; snprintf(header, sizeof(header), "HTTP/1.1 200 OK\r\n" "Content-Type: %s\r\n" "Connection: close\r\n" "\r\n", content_type); /*发送响应头*/ write(client_socket, header, strlen(header)); /*分块读取并发送文件内容*/ char data[BUFFER_SIZE]; size_t bytes_read; /*实际读取的字节数*/ while ((bytes_read = fread(data, 1, BUFFER_SIZE, file)) > 0){ write(client_socket, data, bytes_read); } fclose(file); } close(client_socket); return NULL; } /**************************************************************************************************/ /* PUBLIC_FUNCTIONS */ /**************************************************************************************************/ /**************************************************************************************************/ /* GLOBAL_FUNCTIONS */ /**************************************************************************************************/ int main(){ int server_fd, client_socket; /*服务器和客户端套接字*/ struct sockaddr_in address; /*服务器地址结构*/ int addrlen = sizeof(address); /*TCP*/ if((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0){ perror("socket failed"); exit(EXIT_FAILURE); } /*配置服务器地址*/ address.sin_family = AF_INET; address.sin_port = htons(PORT); address.sin_addr.s_addr = INADDR_ANY; /*绑定套接字*/ if(bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0){ perror("bind failed"); exit(EXIT_FAILURE); } printf("Server listening on port %d...\n", PORT); /*监听*/ if(listen(server_fd,CLIENTS_MAX) < 0){ perror("listen failed"); exit(EXIT_FAILURE); } /*接收客户端连接*/ while(1){ /*阻塞接收客户端链接*/ if((client_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0){ perror("accept failed"); continue; } char client_ip[INET_ADDRSTRLEN]; inet_ntop(AF_INET, &(address.sin_addr), client_ip, INET_ADDRSTRLEN); printf("Accepted connection from %s:%d\n", client_ip, ntohs(address.sin_port)); /*为客户端创建线程*/ pthread_t thread_id; if(pthread_create(&thread_id, NULL, handle_client, &client_socket) < 0){ perror("pthread failed"); close(client_socket); } pthread_detach(thread_id); } return 0; }
08-16
<think>好的,用户现在想了解pthread_createpthread_join和pthread_detach这三个函数。之前用户询问过在GDB调试多线程程序时卡在创建线程的问题,现在可能是在进一步学习多线程编程的基础知识,或者是在解决线程管理相关的问题。需要确保回答清晰,区分这三个函数的用途和区别,尤其是join和detach的不同,因为这两个函数容易混淆。 首先,我需要回顾这三个函数的基本功能和用法。pthread_create用于创建线程,参数包括线程标识符、属性、启动函数和参数。用户可能想知道如何正确使用它,比如传递参数时的注意事项,或者属性设置的影响。然后,pthread_join用于等待线程结束并回收资源,而pthread_detach则是让线程结束后自动释放资源,不需要join。如果用户之前遇到线程卡住的问题,可能和没有正确使用join或detach有关,导致资源泄露或者主线程提前退出。 需要强调线程分离的重要性,避免僵尸线程。同时,要指出使用detach后不能再join,否则会导致错误。此外,可能用户在实际编码中遇到线程未正确回收的问题,或者对线程的生命周期管理不太清楚。这时候,给出示例代码会有帮助,比如展示如何正确创建线程,并使用join或detach来管理。 另外,用户可能想知道这三个函数之间的配合使用场景。比如,何时该用join,何时用detach。比如,主线程需要等待子线程完成时使用join,而如果子线程独立运行,不需要等待,则用detach。同时,要提醒如果既不join也不detach,可能会导致资源泄露,这也是常见错误点。 可能还需要提到错误处理,比如检查这些函数的返回值,确保线程创建和管理成功。此外,线程属性如设置为detach状态,可以在创建时就分离,避免后续调用detach的需要。这些细节能帮助用户更全面地理解线程管理。 最后,总结对比这三个函数,确保用户理解它们各自的作用和使用场景。这样用户在编写多线程程序时,能够正确管理线程的生命周期,避免常见的陷阱,比如资源泄露或者程序异常终止。</think>以下是`pthread_create`、`pthread_join`和`pthread_detach`的详细对比说明: --- ### **1. `pthread_create` - 线程创建** #### **函数原型** ```c int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); ``` #### **核心功能** - 创建新线程,执行`start_routine`函数 - `attr`参数控制线程属性(可设置为`NULL`使用默认属性) - `arg`是传递给线程函数的参数(必须是全局变量或堆内存) #### **示例** ```c void* thread_func(void* arg) { printf("Thread ID: %lu\n", (unsigned long)pthread_self()); return NULL; } int main() { pthread_t tid; pthread_create(&tid, NULL, thread_func, NULL); // ... } ``` --- ### **2. `pthread_join` - 线程同步** #### **函数原型** ```c int pthread_join(pthread_t thread, void **retval); ``` #### **核心功能** - 阻塞当前线程,等待目标线程终止 - 回收线程资源(必须调用,否则会产生"僵尸线程") - 获取线程返回值(通过`retval`参数) #### **示例** ```c void* thread_func(void* arg) { int* result = malloc(sizeof(int)); *result = 42; return result; } int main() { pthread_t tid; void* ret_val; pthread_create(&tid, NULL, thread_func, NULL); pthread_join(tid, &ret_val); printf("Thread returned: %d\n", *(int*)ret_val); free(ret_val); } ``` --- ### **3. `pthread_detach` - 线程分离** #### **函数原型** ```c int pthread_detach(pthread_t thread); ``` #### **核心功能** - 将线程标记为"分离状态" - 分离后的线程终止时会自动释放资源 - 分离后不可再调用`pthread_join` #### **示例** ```c void* thread_func(void* arg) { // 长时间运行的任务... return NULL; } int main() { pthread_t tid; pthread_create(&tid, NULL, thread_func, NULL); pthread_detach(tid); // 分离线程 // 主线程无需等待即可继续执行 while(1) { /* 主线程任务 */ } } ``` --- ### **对比总结** | 特性 | `pthread_create` | `pthread_join` | `pthread_detach` | |---------------------|------------------------|-----------------------------|-----------------------------| | 主要作用 | 创建新线程 | 等待线程结束并回收资源 | 自动回收线程资源 | | 阻塞行为 | 非阻塞 | 阻塞调用线程 | 非阻塞 | | 资源回收 | 不负责 | 显式回收 | 隐式自动回收 | | 返回值获取 | 无 | 可以获取 | 无法获取 | | 调用次数限制 | 每个线程1次 | 每个线程最多1次 | 每个线程最多1次 | | 典型使用场景 | 启动并发任务 | 需要等待线程结果 | 无需关心线程结束状态 | --- ### **最佳实践** 1. **必须二选一**:对每个线程必须调用`pthread_join`或`pthread_detach` 2. **创建即分离**:可以在创建时设置分离属性: ```c pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_create(&tid, &attr, thread_func, NULL); ``` 3. **错误处理**:检查所有pthread函数的返回值(0表示成功,非0为错误码) --- ### **常见问题** 1. **双重join错误**: ```c pthread_join(tid, NULL); pthread_join(tid, NULL); // 会导致未定义行为 ``` 2. **分离后join**: ```c pthread_detach(tid); pthread_join(tid, NULL); // 错误:返回EINVAL ``` 3. **主线程提前退出**: ```c int main() { pthread_t tid; pthread_create(&tid, NULL, thread_func, NULL); return 0; // 主线程退出可能导致进程终止 } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值