Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

线程之间的竞争 #5

Closed
huntinux opened this issue Jun 30, 2016 · 7 comments
Closed

线程之间的竞争 #5

huntinux opened this issue Jun 30, 2016 · 7 comments

Comments

@huntinux
Copy link
Contributor

在main函数中,传递给线程的参数client_sock是一个local variable,会产生竞争吗?
if (pthread_create(&newthread , NULL, (void *)accept_request, (void *)&client_sock) != 0) perror("pthread_create");

比如连接1对应的线程运行前,连接2把client_sock修改了。
是否应该在堆上分配

@sidgwick
Copy link

sidgwick commented Jul 1, 2016

我觉得会. 这种情况, 执行pthread_create的时候, 应该加锁?

@sidgwick
Copy link

sidgwick commented Jul 1, 2016

我试了下, 确实应该加锁:

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

void *thread_a(void *arg)
{
    printf("thread a start\n");
    sleep(2);
    printf("arg value(a): %d\n", *(int *)arg);
    printf("thread a end.\n");

    return NULL;
}

void *thread_b(void *arg)
{
    printf("thread b start\n");
    printf("arg value(b): %d\n", *(int *)arg);
    printf("thread b change *arg to 10\n");
    *(int *)arg = 10;
    printf("thread b end.\n");

    return NULL;
}

int main()
{
    int a = 5;
    pthread_t pthread_a;
    pthread_t pthread_b;

    pthread_create(&pthread_a, NULL, thread_a, (void *)&a);
    sleep(1);
    pthread_create(&pthread_b, NULL, thread_b, (void *)&a);

    pthread_join(pthread_a, NULL);
    pthread_join(pthread_b, NULL);

    return 0;
}

输出:

thread a start
thread b start
arg value(b): 5
thread b change *arg to 10
thread b end.
arg value(a): 10
thread a end.

不过说回来, 解引用就在线程入口处, 感觉一般情况不会出问题. 个人感觉这里用条件变量就好.

@fbnzk
Copy link

fbnzk commented Sep 23, 2016

确实会发生,已经验证过了,因为我们保证不了线程的运行顺序。能想到的解决办法就是加锁,在accept前加锁,在新创建的线程中解锁。

@huntinux
Copy link
Contributor Author

huntinux commented Oct 10, 2016

可以这么改,不必使用锁。因为参数是以值传递的。

 if (pthread_create(&newthread , NULL, (void *)accept_request, (void *)(intptr_t)client_sock) != 0)

accept_request中这样将参数转换为int:

int client = (intptr_t)arg;

@fbnzk
Copy link

fbnzk commented Oct 10, 2016

确实是这样的,huntinux 的方法更好,没必要使用锁,多谢。

@liuyunbin
Copy link

liuyunbin commented Mar 21, 2017

我感觉可以改成以下的内容,使用动态分配,在线程里释放内存空间,参考了UNP

client_sock = (int*)malloc(sizeof(int));
*client_sock = accept(server_sock, (struct sockaddr *)&client_name, &client_name_len);
if (pthread_create(&newthread , NULL, accept_request, client_sock) != 0)
   	perror("pthread_create");

huntinux referenced this issue May 4, 2017
fie problem caused by intptr_t
@EZLippi
Copy link
Owner

EZLippi commented May 15, 2017

fix thread conflict when passing arg as pointer

@EZLippi EZLippi closed this as completed May 15, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants