c线程参数传递

来源:互联网 发布:采购数据分析报表 编辑:程序博客网 时间:2024/04/28 18:04

主线程代码

typedef struct _CLIENT {        int socket;              //客户端socket        char ip[16];            //客户端IP地址    } CLIENT;    for (;;) {        sin_size = sizeof(struct sockaddr_in);        client_fd = accept(server_fd, (struct sockaddr*)&client_addr, (socklen_t*)&sin_size);        if (client_fd == -1) {            continue;        }                CLIENT client;        client.socket = client_fd;        strncpy(client.ip, inet_ntoa(client_addr.sin_addr), 16);                pthread_create(&thread_id, &attr, client_proc, (void*)&client);  //这里传client给子线程    }

子线程代码

void *client_proc(void *arg){    CLIENT client = *(CLIENT*)arg;    int sock = client.socket;    printf("IP_ADDRESS:%s, SOCKET:%d\n", client.ip, sock);}

问题:
子线程里结构CLIENT的值,打印的IP_ADDRESS是正确的,socket也可以接收数据,但就是不能关闭socket(并发的时候,打印的socket值都是相同的)???


引申:
如果只传一个socket参数:
主:pthread_create(&thread_id, &attr, client_proc, (void*)client_fd); 
子:int sock = (int)arg;  //就是正常的


主:pthread_create(&thread_id, &attr, client_proc, (void*)&client_fd);   
子:int sock = *(int*)arg;  //可以接收,但不能关闭。和传多个参数问题相同。


请问怎么正确传多个参数给子线程?
请教各位了,多谢。 
zylthinking 发表于 2011-09-22 11:34
和socket没有半点关系, 你主线程代码中存在线程竞争bug 
leiing 发表于 2011-09-22 11:40
哥们真快。
为什么只传一个socket参数没有问题呢?
要对主线程的client_fd加锁吗?


[quote]和socket没有半点关系, 你主线程代码中存在线程竞争bug
[size=2][color=#999999]zylthinking 发表于 2011-09-22 11:34[/color] [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=21482544&ptid=3598862][img]<http://bbs.chinaunix.net/images/common/back.gif[/img][/url][/size][/quote>] 
zylthinking 发表于 2011-09-22 11:51
你这样吧, 
         CLIENT* client = malloc(sizeof(CLIENT));
         if(client == NULL){
             .....................
         }
        client->socket = client_fd;
        strncpy(client->ip, inet_ntoa(client_addr.sin_addr), 16);




void *client_proc(void *arg)
{
    CLIENT* client = (CLIENT*)arg;
    int sock = client->socket;
    printf("IP_ADDRESS:%s, SOCKET:%d\n", client->ip, sock);


    free(arg);
}


对照着想吧, 如果还想不明白, 就别完socket了, 先将基础补好 
leiing 发表于 2011-09-22 12:15
[quote]你这样吧, 
         CLIENT* client = malloc(sizeof(CLIENT));
         if(client == NULL){
     ...
[size=2][color=#999999]zylthinking 发表于 2011-09-22 11:51[/color] [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=21482652&ptid=3598862][img]<http://bbs.chinaunix.net/images/common/back.gif[/img][/url][/size][/quote>]




这样是可以,多谢。
不过,恕我新手,想不明白,CLIENT client应该是在主线程的栈空间里吧,malloc应该是在主线程的堆空间里,子线程应该有自己的堆栈空间,这样对子线程的区别是什么?


还是想麻烦下哥们普及下基础,多谢。 
zylthinking 发表于 2011-09-22 12:20
和堆啊栈啊的其实也关系不大。
帮你将问题更明显化一些:


    typedef struct _CLIENT {
        int socket;              //客户端socket
        char ip[16];            //客户端IP地址
    } CLIENT;


    for (;;) {
        sin_size = sizeof(struct sockaddr_in);
        client_fd = accept(server_fd, (struct sockaddr*)&client_addr, (socklen_t*)&sin_size);
        if (client_fd == -1) {
            continue;
        }
        
        CLIENT client;
        client.socket = client_fd;
        strncpy(client.ip, inet_ntoa(client_addr.sin_addr), 16);
        
        pthread_create(&thread_id, &attr, client_proc, (void*)&client);  //这里传client给子线程
    }


void *client_proc(void *arg)
{
    [color=Red]sleep(2小时);
[/color]    CLIENT client = *(CLIENT*)arg;
    int sock = client.socket;
    printf("IP_ADDRESS:%s, SOCKET:%d\n", client.ip, sock);

leiing 发表于 2011-09-22 12:38
是不是因为栈里的client自动释放了?而堆里的client要手动释放,所以子线程里才能访问? 
zylthinking 发表于 2011-09-22 12:44
怎么还理解不了呢, 是因为栈中的 client 被覆盖写了
你将它地址传给其他线程, 如果其他线程首先 sleep 了2小时再访问这个地址, 那么在它睡眠的2小时内, 主线程不知将这个结构的数据重新赋值多少次了




明白了??? 
leiing 发表于 2011-09-22 12:50
明白了,多谢zylthinking这么耐心。:handshake 
AD8018 发表于 2011-09-22 13:14
不喜欢malloc, 我喜欢在
pthread_create(&thread_id, &attr, client_proc, (void*)&client);  //这里传client给子线程
之后,
加一段代码等待
CLIENT client = *(CLIENT*)arg;
完成 
net_robber 发表于 2011-09-22 14:16
[quote]不喜欢malloc, 我喜欢在
pthread_create(&thread_id, &attr, client_proc, (void*)&client);  //这里传cl ...
[size=2][color=#999999]AD8018 发表于 2011-09-22 13:14[/color] [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=21483026&ptid=3598862][img]<http://bbs.chinaunix.net/images/common/back.gif[/img][/url][/size][/quote>]




    在线程创建后,赋值语句执行前,你怎么确认变量没有被覆盖?? 
雨过白鹭洲 发表于 2011-09-22 15:46
[b]回复 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=21483347&ptid=3598862]11#[/url] [i]net_robber[/i] [/b]




    他的确认就是忽略这个竞争条件。。。


这样做99.9%的情况下都不会有问题,除非系统负载非常大,线程一直得不到调度执行,主线程for循环却在执行并释放了原来的client才会出错。。 
fanronghua 发表于 2011-09-22 15:52
CLIENT client;
放两个 线程外面。 
leiing 发表于 2011-09-22 16:06
[quote]CLIENT client;
放两个 线程外面。
[size=2][color=#999999]fanronghua 发表于 2011-09-22 15:52[/color] [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=21483923&ptid=3598862][img]<http://bbs.chinaunix.net/images/common/back.gif[/img][/url][/size][/quote>]




    这样就要加锁了吧? 
leiing 发表于 2011-09-22 16:10
[quote]回复  net_robber 




    他的确认就是忽略这个竞争条件。。。


这样做99.9%的情况下都不会有问题,除 ...
[size=2][color=#999999]雨过白鹭洲 发表于 2011-09-22 15:46[/color] [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=21483895&ptid=3598862][img]<http://bbs.chinaunix.net/images/common/back.gif[/img][/url][/size][/quote>]




    看来,要好好学下多线程并发的问题。 
AD8018 发表于 2011-09-22 22:58
[quote]回复  net_robber 




    他的确认就是忽略这个竞争条件。。。


这样做99.9%的情况下都不会有问题,除 ...
[size=2][color=#999999]雨过白鹭洲 发表于 2011-09-22 15:46[/color] [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=21483895&ptid=3598862][img]<http://bbs.chinaunix.net/images/common/back.gif[/img][/url][/size][/quote>]


    为什么不在CLIENT结构中,加个semaphore用作等待呢?
我认为再烂的semahpre,也强过malloc的时间开销。 
AD8018 发表于 2011-09-22 23:04
尤其是嵌入式系统,这种多线程场合下,
更应该用semahpre,不用malloc,
少一个分配,少一个内存切碎片的机会。 
雨过白鹭洲 发表于 2011-09-23 08:54
[b]回复 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=21485357&ptid=3598862]17#[/url] [i]AD8018[/i] [/b]




1. 这样写出来的代码可能有些怪,就为了线程把这个传入参数复制一份就等待?至少我觉得挺怪的
2. 主线程malloc,子线程使用并负责释放的方式挺好,至于内存碎片的问题,需要我们考虑得这么细吗?难道malloc都不用了? 
zylthinking 发表于 2011-09-23 09:50
[quote]回复  AD8018 




1. 这样写出来的代码可能有些怪,就为了线程把这个传入参数复制一份就等待?至少我觉得 ...
[size=2][color=#999999]雨过白鹭洲 发表于 2011-09-23 08:54[/color] [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=21486645&ptid=3598862][img]<http://bbs.chinaunix.net/images/common/back.gif[/img][/url][/size][/quote>]


个人喜好, 无所谓的事情, 用不着在这些细节上较真 

0 0
原创粉丝点击