Linux-下面的多线程程序哪里出了问题,为什么会得到下面的结果?

发布于 2017-01-02 18:56:09 字数 591 浏览 1288 评论 3

下面的多线程程序哪里出了问题,为什么会得到下面的结果?

#include "csapp.h"//本头文件可网上下载!
#define N 4

void *thread(void *vargp);

int main()
{
pthread_t tid[N];
int i;

for(i=0;i<N; i++)
Pthread_create(&tid[i], NULL, thread, &i);
for(i=0;i<N; i++)
Pthread_join(tid[i], NULL);
exit(0);
}

/* Thread routine */
void *thread(void *vargp)
{
int myid = *((int *)vargp);
printf("Hello from thread %dn", myid);
return NULL;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

清晨说ぺ晚安 2017-10-23 21:13:19

是因为传的是指针的缘故,主线程和thread线程访问的是同一个内存单元。

线程创建是并不能保证哪个线程先运行:是新创建的线程还是调用线程。

将程序做如下修改:

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

#define N 4

void *thread(void *vargp);

int main()
{
    pthread_t tid[N];
    int i;
    i = 1;
    printf("before pthread_create, i=%dn", i);
/*
    for(i=0;i<N; i++)
    {
        pthread_create(&tid[i], NULL, thread, &i);
    }
    for(i=0;i<N; i++)
        pthread_join(tid[i], NULL);
    */
    pthread_create(&tid[0], NULL, thread, &i);
    pthread_join(tid[0], NULL);

    printf("in main thread: i=%dn", i);
    exit(0);
}

 /* Thread routine */
void *thread(void *vargp)
{
     int* myid = (int *)vargp;
     *myid = 100;

    printf("Hello from thread: i=%dn", (int)*myid);
    return NULL;
}

运行结果:

ajaxhe@bbs:~/program/thread$ gcc join.c -lpthread
ajaxhe@bbs:~/program/thread$ ./a.out
before pthread_create, i=1
Hello from thread: i=100
in main thread: i=100
甜柠檬 2017-10-14 21:31:15

你传进去的是个指针,这个指针指向的i在创建完之后立即就变了,而这时候线程还不一定读取到这个值。所以输出的结果是不确定的。
其实虽然参数类型是void*,但实际上也可以通过强制转换来传递一个int进去的:

 #include "csapp.h"//本头文件可网上下载!
#define N 4

void *thread(void *vargp);

int main()
{
pthread_t tid[N];
int i;

for(i=0;i<N; i++)
Pthread_create(&tid[i], NULL, thread, (void*)i); //注意这里
for(i=0;i<N; i++)
Pthread_join(tid[i], NULL);
exit(0);
}

/* Thread routine */
void *thread(void *vargp)
{
int myid = (int)vargp; //还有这里
printf("Hello from thread %dn", myid);
return NULL;
}

虐人心 2017-02-19 01:24:26

因为楼主传递的是一个i的指针,比如此时住线程正在创建线程1,当线程1运行的时候此时i的地址对应的值是1,但是这个时候分配给线程1的cpu时间到了,此时又该主线程运行了,主线程把i的值改为了2,这时候线程1又被分配了几个cpu运行时间,此时线程1执行打印命令而此时i的地址对应的值已经不是穿件来时候的1了,而是被主线程++之后的2.
如果希望正确打印
1.可以创建一个int数组,预先把1,2,3,4,5,...这些值赋值进去,当线程creat的时候把他们的地址挨个穿件去。
2.可以设置同步,但是这种方法明显就是把问题复杂化了。
同步代码如下所示

 pthread_cond_t cond;
pthread_mutex_t mutex;
int var=0;
.........
//main方法开始
pthread_cond_init(&cond,NULL);
pthread_mutex_init(&mutex,NULL);
for(int i =0;i<N;i++)
{
var=0;
pthread_mutex_lock(&mutex);
pthread_create(&tid[i],NULL,threadfunc,&i);
//------创建线程之后等待条件变量唤醒主线程继续执行---//
while(var!=1)
pthread_cond_wait(&cond,&mutex);
pthread_mutex_unlock(&mutex);
}
.........
//main方法结束
void* threadfunc(void* i)
{
pthread_mutex_lock(&mutex);
printf("thread %d n",*((int*)i));
//---设置条件var=1,唤醒等待的主线程----//
var=1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文