【问题标题】:Why do threads not work properly?为什么线程不能正常工作?
【发布时间】:2016-01-28 13:23:11
【问题描述】:

我正在解决一个大学练习题。父进程通过管道将在文件中读取的数字 (nThreads) 提供给子进程。子进程必须执行 nThreads 个线程并休眠 nThreads 秒,每个线程必须打印子进程给定的随机数并休眠该随机数秒。 进程打印一切正常,但线程没有。我的代码有什么问题?

...
#include <pthread.h>

void exitError() {
 write(2, "Error!\n", 7);
 exit(1);
}

void *doThread(void* args) {
 long rnd = (long)args;
 printf("Random number = %ld", rnd);
 sleep(rnd);
 pthread_exit((void *)0);
}

int main (int argc, const char * argv[]) {

 int pid, n, piped[2];

 pipe(piped);

 if ((pid=fork()) == -1) {
    write(1, "Error!\n", 4);
    exit(1);
 }
 else if (pid == 0) {   //son
    int nThreads;
    close(piped[1]);
    read(piped[0], &nThreads, 2);
    printf("\nI have to create %d threads\n\n", nThreads);
    pthread_t *threads;
    threads = (pthread_t *) malloc(nThreads*sizeof(pthread_t));

    int random;
    random = rand();
    pthread_create(&threads[nThreads], NULL, doThread, random);

    sleep(nThreads);
    exit(0);
 }
 else {                 //father
    signal(SIGALRM, exitError);
    alarm(10);
    if (argc != 2) {
        write(1, "Command error!\n", 24);
    }   
    int fd = open(argv[1], O_RDONLY);
    char buf[1];
    n = read(fd, buf, 1);
    int nThreads = atoi(buf);
    printf("I say %d to my son\n", nThreads);
    close(piped[0]);
    write(piped[1], &nThreads, 2);
    wait(NULL);
    alarm(0);
    exit(0);
 }

 return 0;
}

如果我做错了什么,请原谅我,这是我第一次在这里提出问题。

【问题讨论】:

  • 你需要pthread_join()你的线程。
  • int* random; *random = ... 是错误的。致命错误。
  • 对不起,你是对的。我修复了它,但线程似乎仍然不起作用。
  • 除非您使用的是旧的 16 位系统,否则sizeof(int)(或sizeof(nThreads)等于2
  • @Pottercomuneo:您对int * 问题的“修复”当然是不正确的。您似乎不确定是 intlong 还是 long*。这些东西是不可互换的。此外,您仍然不使用您的线程pthread_join(),因此您正在加速进程终止,并且它可能会在random()(或&amp;random,如案件目前)。

标签: c multithreading pthreads


【解决方案1】:

有不少错误:

首先,您将指针传递给int random,但在线程中您将参数(指针)转换为数字。您必须将int random 转换为指针,或者在线程中将args 转换为long * 并从该指针读取内存。一旦您启动多个线程,后者实际上将停止工作,因为您将同时更改变量内容,甚至离开该变量的范围。

其次,您无需等待线程。使用pthread_join 等待线程。

第三,你只运行单线程,你需要创建从0nThreads的循环,一旦启动它们,在类似的循环中调用pthread_join

第四,int 的大小在大多数平台上是 4,而您只发送 2 个字节。这可能适用于低端平台,但在大端平台上会失败。将sizeof(int) 用于writeread,使其更便携。

【讨论】:

  • 还有在单个char 上调用atoi() 的问题(显然未终止)...
  • 谢谢,我理解了我所有的错误。有一件事让我想到它,练习说“主线程不必等待其他线程结束”。这就是为什么我认为我不必使用pthread_join。错了吗?
  • 好吧,如果有人说,您可能不必这样做。但是,当您退出主线程而不是其他线程时,我不确定可移植性。它在不同系统上的工作方式可能不同,有的可能会退出整个进程,有的可能会等待其他线程。其次,在这种情况下,您必须确保不要将指针传递给random,因为它会超出范围并且不再可从线程中使用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-16
  • 2019-01-04
相关资源
最近更新 更多